字节/字符缓冲流 – 提高效率

  • 2019 年 10 月 3 日
  • 筆記

字节缓冲流


  • 缓冲流可以提高效率,基本原理是在创建对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统的IO次数,从而提高读写效率

缓冲输出流:BufferedOutputStream


  • java.io 类 BufferedOutputStream
    继承者 java.io.OutputStream
    继承者 java.io.FilterOutputStream
    继承者 java.io.BufferedOutputStream

  • 构造方法:
    1. BufferedOutputStream(OutputStream out)
      创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
      OutputStream:可以传递一个FileOutputStream,有个默认区数组大小

    2. BufferedOutputStream(OutputStream out, int size)
      创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。

  • 使用步骤
    1. 创建FileOutputStream对象,其构造方法绑定输出文件位置
    2. 创建BufferedOutputStream对象,构造方法中传入OutputStream对象,使用多态,传入1的参数。
    3. 使用BufferedOutputStream方法write,把数据写入到内部缓冲区,不是写入文件中
    4. 使用BufferedOutputStream的方法flush由数据缓冲区刷新到文件中
    5. 释放资源,close方法会先调用flush方法
package bufferStream;    import java.io.BufferedOutputStream;  import java.io.FileOutputStream;  import java.io.IOException;    public class bufferStream {      public static void main(String[] args) throws IOException {          //1.创建一个输出流对象,绑定输出文件          FileOutputStream out = new FileOutputStream("b.txt");            //2.创建一个输出缓冲流对象,          BufferedOutputStream bufferOut = new BufferedOutputStream(out);            //3.从内存读入多个数据到默认长度的缓冲区数组          bufferOut.write("nihaoya".getBytes());            //4.将输入缓冲区的数据数组写入文件          bufferOut.flush();            //5.释放资源,包含flush方法          bufferOut.close();      }  }  

字节缓冲输入流:BufferedInputStream


import java.io.*;    public class bufferStream {      public static void main(String[] args) throws IOException {          //1.创建一个输入流对象,绑定输入文件          FileInputStream fileInputStream = new FileInputStream("b.txt");          //2.创建一个输入缓冲流对象,          BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream,1024);  /*************************************************          //3.记录每次读到的字节值,这里还是一个字节一个字节的读          int len = bufferedInputStream.read();          while((len=bufferedInputStream.read()) != -1){              System.out.println(len);          }          189          160          229          165          189          229          145          128          utf-8编码中,每个中文字符占三个字节  *******************************************/          //3.创建字节数组,存储读入的数据          byte[] bytes = new byte[1024];          //记录每次读的有效字符长度          int len1 = 0;          //当读取的有效字符数为结束位时,返回-1          while ((len1 = bufferedInputStream.read(bytes)) != -1){              System.out.println(new String(bytes,0,len1));          }          //4.释放缓冲流的同时释放了字节输入流          bufferedInputStream.close();      }  }

文件复制 – 提高效率,牺牲内存


import java.io.*;    public class Test {      public static void main(String[] args) throws IOException {          //绑定复制对象,输入内存          FileInputStream filein = new FileInputStream("C:\Users\Administrator\Pictures\1.jpg");          BufferedInputStream bufin = new BufferedInputStream(filein);            //绑定输出的文件位置,若没有,则自动生成该文件          FileOutputStream fileout=new FileOutputStream("2.jpg");          BufferedOutputStream bufout=new BufferedOutputStream(fileout);            long start=System.currentTimeMillis();  /******************************************************************          //先读后写,len为读取字节值,先读入字节输入缓冲区,若读取长度超过缓冲数组长度,则会刷新缓冲数组,写入文件          int len = 0;          while ((len = bufin.read()) != -1) {              bufout.write(len);          }            //释放流,同时释放构造方法中对象的流          bufin.close();          bufout.close();            long end =System.currentTimeMillis();          System.out.println("该复制花费:"+(end-start)+"ms"); //复制2MB左右,花费79ms   ********************************************************************/          //提高效率,将读取的字节放入字节数组          byte[] bytes=new byte[1024];          int len = 0;          while ((len = bufin.read(bytes)) != -1) {              bufout.write(bytes);          }            //释放流,同时释放构造方法中对象的流          bufin.close();          bufout.close();            long end =System.currentTimeMillis();          System.out.println("该复制花费:"+(end-start)+"ms"); //复制2MB左右,花费27ms      }  }

字符缓冲输入流:BufferedWriter


  • java.lang.Object
    继承者 java.io.Writer
    继承者 java.io.BufferedWriter

  • 构造方法:

    • BufferedWriter(Writer out)
      创建一个使用默认大小输出缓冲区的缓冲字符输出流。
    • BufferedWriter(Writer out, int sz)
      创建一个使用给定大小输出缓冲区的新缓冲字符输出流
  • 特有的成员方法:

    • void newLine()
      会根据不同的操作系统,获取不同的行分隔符
import java.io.BufferedWriter;  import java.io.FileWriter;  import java.io.IOException;    public class CharBuffered {      public static void main(String[] args) throws IOException {          //1.创建字符缓冲输出流对象          BufferedWriter bufwr = new BufferedWriter(new FileWriter("b.txt"));            //2.会将读取的字符放入内存,一个字符缓冲数组          bufwr.write("大大大大大大爷");          //根据系统进行换行          bufwr.newLine();          //追加内容          bufwr.write("你好");          bufwr.write("好吗");          bufwr.flush();          bufwr.close();      }  }  

字符缓冲输入流:BufferedReader


  • java.lang.Object
    继承者 java.io.Reader
    继承者 java.io.BufferedReader

  • 构造方法:
    • BufferedReader(Reader in)
      创建一个使用默认大小输入缓冲区的缓冲字符输入流。
    • BufferedReader(Reader in, int sz)
      创建一个使用指定大小输入缓冲区的缓冲字符输入流。
  • 特有的成员方法:

    • String readLine()
      读取一个文本行,行的终止符号,通过以下字符认为某行终止换行换行(n)、回车(r)或回车后直接跟着换行。但返回值不包含终止符号
import java.io.BufferedReader;  import java.io.FileReader;  import java.io.IOException;    public class BufferedReader01 {      public static void main(String[] args) throws IOException {          //1.创建字符缓冲输入流对象,构造方法由字符输入流绑定输入地址          BufferedReader bufre = new BufferedReader(new FileReader("b.txt"));            //2.使用read/readLine读取文本,readLine读取一行,返回的是字符串          String str = null;          while((str = bufre.readLine()) != null){              System.out.println(str);          }          /********          大大大大大大爷          你好好吗          ********/        }  }  

练习:文本内容排序


  • 文本段落编号后用双列集合,根据key进行排序
import java.io.*;  import java.util.HashMap;  import java.util.Set;    public class Practice {      public static void main(String[] args) throws IOException {          //1.字符缓冲输入流绑定文件位置          BufferedReader bufre = new BufferedReader(new FileReader("b.txt"));          //2.字符缓冲输出流绑定输出文件位置          BufferedWriter bufwr = new BufferedWriter(new FileWriter("a.txt"));            //3.双列集合放入循环外,便于在作用域外使用          HashMap<String,String> temp= new HashMap<>();            //4.读入到内存中,写入双列集合中          String str = null;          while((str = bufre.readLine()) != null){              //看看文件内容              System.out.println(str);              //切割成两部分              String[] spli = str.split("\.");              //HashMap存储元素,利用HashMap自动升序排序              temp.put(spli[0],spli[1]);          }            System.out.println("n=====================================n");          //遍历下双列集合,同时写入另一个文件          for (String key:temp.keySet()) {              String value = temp.get(key);              System.out.println(key + "."+value);              bufwr.write(value);              //加newLine方法换行              bufwr.newLine();              //注:刷新写入              bufwr.flush();          }            //释放资源,先关输出流          bufwr.close();          bufre.close();      }  }