21IO流 和缓冲流 和处理流
IO流本质就是数据传输的一套机制 Input OutPut Stream 输入输出流
根据数据传输的方向:1.往内存传输数据----输入流
2.内存往外面传数据------输出流
按照流的角色分,可以分节点流和处理流
根据数据传输的方式分为:1.字节流2.字符流
javaIO流的四大基本流
字符流 | 字节流 | |
输出流 | 字符输出流(Writer) | 字节输出流(OutputStream) |
输入流 | 字符输入流(Reader) | 字节输入流(InputStream) |
四大基本流对应的类都是抽象类
数据存储位置(数据传输的场景):硬盘、内存、网络、IO设备(键盘,鼠标。。。)
硬盘:
往硬盘上一个txt文件写入数据:字符输出流
采用其中的子类:FlieWriter
public static void main(String[] args) throws IOException { //创建一个FileWriter对象 //检测路径正确与否 //如果路径正确但是没有具体的文件就会创建一个空文件 //如果文件已经存在就会再创建一个空文件覆盖之前的文件内容 //保证再写数据之前有一个空文件 FileWriter fw=new FileWriter("D:\\1.txt"); //写数据 //底层是基于缓冲区进行数据传输的 //默认要求缓冲区数据装满才能进行传输 //下面的数据没有装满,缓冲区就没有进行传输 fw.write("您好"); //冲刷缓冲区 //不管缓冲区数据有没有存满都要进行传输 //防止数据滞留在缓冲区产生数据丢失的问题 fw.flush(); //关闭连接通道 ----关流 //在关闭通道之前会自动冲刷缓冲区的操作 fw.close(); //强制对象值为null //把对象置为无用对象,在某个时间进行垃圾回收 fw=null; }
捕获IO流输出异常处理
1.在try catch外进行声明对象,在try块里进行对象的初始化
2.保证对象已经进行正常的初始化,才能进行关流操作
3.不管你有没有关流成功与否,都要对我们的对象置为无用对象,等待回收
4.流关闭失败有可能是在自动冲刷缓冲区之前,保证数据不能滞留在缓冲区,所以我们需要手动冲刷缓冲区
public static void main(String[] args) { //1.声明FileWriter对象 FileWriter fw=null; //保证有值 不能保证try块里一定能赋值 try { //对象真实赋值 fw=new FileWriter("D:\\2.txt"); //写入数据 fw.write("123"); //4.手动冲刷缓存区 fw.flush(); }catch (IOException e) { e.printStackTrace(); } finally {//不管try块里代码正确与否都要关流 if(fw!=null)//2.保证对象初始化成功,不为Null,这样才能正确调用关流方法 { try { fw.close(); //关流有可能失败 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { //3.对象置为无用对象----垃圾回收 fw=null; } } } }
从一个硬盘的txt文件读取数据 字符输入流 文件 FileReader
public static void main(String[] args) throws IOException { //创建FileReader对象 FileReader rd=new FileReader("D:\\2.txt"); //读取数据 //返回的是读取到的字符的编码值 //读取结束的标志是返回一个-1 int len=-1; //提供一个变量共给读取数据覆盖 while((len=rd.read())!=-1) //避免读取两次情况 System.out.println((char)len);
//关流---输入流没有缓冲区
rd.close(); }
因为FileReader没有缓冲区,所以读取的时候是一个个读取的读取效率低下,所以我们需要自己创建一个缓冲区进行读取
public static void main(String[] args) throws IOException { // 创建FileReader对象 FileReader rd=new FileReader("D:\\3.txt"); //读取数据 //自建缓冲区--数组---字符流---字符数组 char[] cs=new char[5]; int len=-1; while((len=rd.read(cs))!=-1) {//读到的内容存放在数组中 System.out.println(new String(cs,0,len));//将字符数组转成字符串做输出 } //关流 rd.close(); } }
结果:
45656
46584
89849
848
public static void main(String[] args) throws IOException { // 创建FileReader对象 FileReader rd=new FileReader("D:\\3.txt"); //读取数据 //自建缓冲区--数组---字符流---字符数组 char[] cs=new char[5]; int len=-1; while((len=rd.read(cs))!=-1) {//读到的内容存放在数组中 System.out.println(new String (cs)); } //关流 rd.close(); }
45656
46584
89849
84849
rd.read(cs)返回的是放进到cs数组中的元素个数和读到的字符,rd.read()把读到的字符做返回。
复制文件实例
//通过字符流实现文件复制 public class FileCopyText1 { public static void main(String[] args) { // long start=System.currentTimeMillis(); //声明IO流对象 FileReader reader=null; FileWriter writer=null; try { //对象的初始化---指明两个文件的路径 reader=new FileReader("E:\\a1.txt"); writer=new FileWriter("D:\\javase\\a1.txt"); //读取数据 //自建数组---缓冲区 char[] cs=new char[1024*1024*10];//读取1M int len=-1;//接收每次返回的字符个数 while((len=reader.read(cs))!=-1){ //写出数据 writer.write(cs, 0, len); } //冲刷缓冲区 writer.flush(); } catch (Exception e) { // TODO: handle exception }finally { //保证流对象不能为null1去关流 if(reader!=null) try { reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { //置为无用对象 reader=null; } if(writer!=null) try { writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { //无用对象· writer=null; } } // long end=System.currentTimeMillis(); System.out.println(end-start); } }
缓冲流(用于提供缓冲区):这个提供的的缓冲区不同于输出流自带的缓冲区,我们自己写的缓冲区大小,效率不太好,所以我们想让java给我们提供一个缓冲区
BufferedReader: 给字符输入流提供一个强大的缓冲区 有一个好的方法 readLine();
public static void main(String[] args) throws IOException { //创建缓冲流对象 //真正读取内容的流对象是FileReader,字符输入流 //缓冲流对象只是给字符输入流提供一个缓冲区 BufferedReader br=new BufferedReader(new FileReader("D:\\3.txt")); //读取一行(只要没有换行符那么就是一行)结束标志是null String s=""; while((s=br.readLine())!=null) System.out.println(s); }
统计工作空间.java文件中有多少行代码
public class CountCodeLine { //统计数 static int count; public static void main(String[] args) throws IOException { //文件对象---指定工作空间 File file=new File("D:\\workspace"); //调用方法 countLine(file); // System.out.println(count); } //获取到所有.java文件并统计有多少行 public static void countLine(File file) throws IOException{ //判断是否是文件夹 if(file.isDirectory()){ //获取当前目录下的所有信息 File[] fs=file.listFiles(); //遍历数组---递归调用 for (File f : fs) { countLine(f); } }else if(file.getName().endsWith(".java")){//文件 //一定都是.java文件 //读取文件 BufferedReader br=new BufferedReader (new FileReader(file)); //进入循环---统计有多行 while(br.readLine()!=null){//走一次循环有一行代码 count++; } } } }
BufferedWriter:给字符输出流提供一个更大的缓存区
public class BufferedWriterDemo { public static void main(String[] args) throws IOException { // BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\b.txt")); //写出数据 bw.write("abc"); //换行---不管具体什么的操作系统 //不同操作系统的换行符不一样 //Windows---\r\n linux---\n bw.newLine(); bw.write("123"); //关流--冲刷缓冲区 bw.close(); } }
处理流
1.处理流的用法