位元組/字元緩衝流 – 提高效率

  • 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();      }  }