Java IO流之緩沖流(深入淺出學習)


緩沖流概述

緩沖流,也叫高效流。能夠高效讀寫緩沖流,能夠轉換編碼的轉換流,能夠持久化存儲對象的序列化對象等等。它是四個基本File流的增強,所以也是4個流,按照數據類型分類。

  • 字節緩沖流:BufferedInputStream,BufferedOutputStream
  • 字符緩沖流:BufferedReader,BufferedWriter

緩沖流的基本原理,是在創建流對象時,會創建一個內置的默認大小的緩沖區數組,通過緩沖區讀寫,減少系統IO讀取次數,從而提高讀寫的效率。

字節緩沖流

構造方法

BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)
// 創建一個新的字節緩沖輸入流

BufferedOutputStream(OutputStream out) // 將數據寫入指定的底層輸出流
BufferedOutputStream(OutputStream out, int size) // 將具有指定緩沖區大小的數據寫入指定的底層輸出流
// 創建一個新的字節緩沖輸出流
參數:
InputStream in:字節輸入流
OutputStream out:字節輸出流
int size:緩沖區大小,不寫的話,默認

BufferedOutputStream —— 字節緩沖輸出流

舉例:把數據寫入到文件中

使用步驟:

1.創建FileOutputStream對象,構造方法中綁定要輸出的目的地。
2.創建BufferedOutputStream對象,構造方法中傳遞FileOutputStream對象,提高FileOutputStream對象效率。
3.使用BufferedOutputStream對象中的方法write,把數據寫入到內部沖區中。
4.使用BufferedOutputStream對象中的方法flush,把內部沖區中的數據,刷新到文件中。
5.釋放資源(會先調用flush方法刷新數據,第4步可以省略)。
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DemoBufferedOutputStream {
    public static void main(String[] args) throws IOException {
        method();
    }

    public static void method() throws IOException {
        // 創建FileOutputStream對象,構造方法中綁定要輸出的目的地。
        FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/BufferedOutputStream.txt", true);

        // 創建BufferedOutputStream對象,構造方法中傳遞FileOutputStream對象,提高FileOutputStream對象效率。
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        // 使用BufferedOutputStream對象中的方法write,把數據寫入到內部沖區中。
        byte[] bytes = "abc".getBytes();
        bos.write(bytes);

        // 使用BufferedOutputStream對象中的方法flush,把內部沖區中的數據,刷新到文件中。
        bos.flush();

        // 釋放資源(會先調用flush方法刷新數據,第4步可以省略)。
        bos.close();
        fos.close();

    }
}

運行生成文件BufferedOutputStream.txt文件,文件的內容如下:

img

BufferedInputStream —— 字節緩沖輸入流

舉例:讀取文件上例中生成的BufferedOutputStream.txt文件。

使用步驟:

1.創建FileInputStream對象,構造方法中綁定要讀取的效據源。
2.創建BufferedInputStream對象,構造方法中傳遞FileInputStream對象,提高FileInputsStream對象的讀取效率
3.使用BufferedInputStream對象中的方法read,讀取文件。
4.釋放資源。
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class DemoBufferedInputStream {
    public static void main(String[] args) throws IOException {
        method();
    }

    private static void method() throws IOException {
        // 創建FileInputStream對象,構造方法中綁定要讀取的效據源。
        FileInputStream fis = new FileInputStream(
                "/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/BufferedOutputStream.txt"
        );

        // 創建BufferedInputStream對象,構造方法中傳遞FileInputStream對象,提高FileInputsStream對象的讀取效率
        BufferedInputStream bis = new BufferedInputStream(fis);

        // 使用BufferedInputStream對象中的方法read,讀取文件。
        int len1 = bis.read();
        System.out.println(len1);

        int len2 = bis.read();
        System.out.println(len2);

        int len3 = bis.read();
        System.out.println(len3);

        // 第四次讀取的時候,所以的字節都已經給讀取過了,返回-1
        int len4 = bis.read();
        System.out.println(len4);

        // 釋放資源
        bis.close();
        fis.close();
    }
}

控制台輸出:

97
98
99
-1

效率測試

/**
 * 舉例:不同方法,拷貝圖片的速度,來測試效率
 * 
 * 文件復制的步驟(不使用緩沖):
 * 1.創建一個字節輸入流對象,構造方法中綁定要讀取的數據源。
 * 2.創建一個字節輸出流對象,構造方法中綁定要寫入的目的地。
 * 3.使用字節輸入流對象中的方法read,讀取文件。
 * 4.使用字節輸出流中的方法write,把讀取到的字節寫入到目的地的文件中。
 * 5.釋放資源。
 * 
 * 文件復制的步驟(使用緩沖):
 * 1.創建字節緩沖輸入流對象,構造方法中傳遞字節輸入流。
 * 2.創建字節緩沖輸出流對象,構造方法中傳遞字節輸岀流。
 * 3.使用字節緩沖輸入流對象中的方法read,讀取文件。
 * 4.使用字節緩沖輸出流中的方法wite,把讀取的數據寫入到內部緩沖區中。
 * 5.釋放資源(會先把緩沖區中的數據,刷新到文件中)。
 */

定義三個方法:

/**
 * 不使用緩沖字節輸入輸出流,
 * 一個一個字節的方式。
 */
public static void method1() throws IOException {
    FileInputStream fis = new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg");
    FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy1.jpg");

    int len = 0;
    while ((len = fis.read()) != -1) {
        fos.write(len);
    }

    fis.close();
    fos.close();
}
/**
 * 不使用緩沖字節輸入輸出流,
 * 一次讀取多個字節的方式。
 */
public static void method2() throws IOException {
    FileInputStream fis = new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg");
    FileOutputStream fos = new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy2.jpg");

    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = fis.read(bytes)) != -1) {
        fos.write(bytes, 0, len);
    }

    fis.close();
    fos.close();
}
/**
 * 使用緩沖字節輸入輸出流
 */
public static void method3() throws IOException {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/test.jpg"));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("/Users/liyihua/IdeaProjects/Study/src/view/study/demo33/copy3.jpg"));

    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = bis.read(bytes)) != -1) {
        bos.write(bytes, 0, len);
    }

    bos.close();
    bis.close();
}

測試這三個方法的效率:

public class DemoEfficiency {
    public static void main(String[] args) throws IOException {
        // 方法1效率測試
        long method1StartTime = System.currentTimeMillis();
        method1();
        long method1EndTime = System.currentTimeMillis();
        System.out.println("使用方法1,文件復制耗時(毫秒):" + (method1EndTime - method1StartTime));

        // 方法2效率測試
        long method2StartTime = System.currentTimeMillis();
        method2();
        long method2EndTime = System.currentTimeMillis();
        System.out.println("使用方法2,文件復制耗時(毫秒):" + (method2EndTime - method2StartTime));

        // 方法3效率測試
        long method3StartTime = System.currentTimeMillis();
        method3();
        long method3EndTime = System.currentTimeMillis();
        System.out.println("使用方法3,文件復制耗時(毫秒):" + (method3EndTime - method3StartTime));
    }
}

控制台輸出:

使用方法1,文件復制耗時(毫秒):30268
使用方法2,文件復制耗時(毫秒):53
使用方法3,文件復制耗時(毫秒):21

文件大小:8,392,028 字節(磁盤上的 8.4 MB)

運行程序,生成:copy1.jpg、copy2.jpg、copy3.jpg三個文件

可以看出,使用緩沖字節輸入輸出流效率極高。

字符緩沖流

構造方法

BufferedReader(Reader in)
BufferedReader(Reader in, int sz)
// 創建一個新的緩沖字符輸入流

BufferedWriter(Writer out)
BufferedWriter(Writer out, int sz)
// 創建一個新的緩沖字符輸出流
參數:
Writer out:字符輸出流
Reader in:字符輸入流
int sz:緩沖區大小

BufferedWriter —— 字符緩沖輸出流

舉例:把字符文件寫入到文件中

使用步驟:

1.創建字符緩沖輸岀流對象,構造方法中傳遞字符輸岀流。
2.調用字符緩沖輸出流中的方法write,把數據寫入到內存緩沖區中。
3.調用字符緩沖輸出流中的方法flush,把內存緩沖區中的數據,刷新到文件中。
4.釋放資源。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class DemoBufferedWrite {
    public static void main(String[] args) throws IOException {
        method();
    }

    private static void method() throws IOException {
        // 創建字符緩沖輸岀流對象,構造方法中傳遞字符輸岀流。
        BufferedWriter bw = new BufferedWriter(new FileWriter("/Users/liyihua/IdeaProjects/Study/src/view/study/demo34/BufferedWriter.txt"));
        
        // 調用字符緩沖輸出流中的方法write,把數據寫入到內存緩沖區中。
        bw.write("你好吖!字符緩沖輸出流");
        
        // 調用字符緩沖輸出流中的方法flush,把內存緩沖區中的數據,刷新到文件中。
        bw.flush();
        
        // 釋放資源。
        bw.close();
    }
}

運行結果,生成BufferedWriter.txt文件,文件內容如下:

img

如果需要換行,可以使用該類里的newLine()方法。該方法如同println()方法。

BufferedReader —— 字符緩沖輸入流

這個類有一個特有的成員方法:

String readLine()
// 讀取一個文本行(讀取一行數據)。
返回值:
包含該行內容的字符串,不包含任何行終止符,如果已到達流末尾,則返回null。

行的終止符:換行('\n')、回車('\r')、回車后直接跟着換行('\r\n')

舉例:讀取一個文件中的每行字符。

使用步驟:

1.創建字符緩沖輸入流對象,構造方法中傳遞字符輸入流。
2.使用字符緩沖輸入流對象中的方法read/readLine,讀取文本。
3.釋放資源。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class DemoReader {
    public static void main(String[] args) throws IOException {
        method();
    }

    private static void method() throws IOException {
        // 創建字符緩沖輸入流對象,構造方法中傳遞字符輸入流。
        BufferedReader br = new BufferedReader(new FileReader("/Users/liyihua/IdeaProjects/Study/src/view/study/demo34/test"));

        // 使用字符緩沖輸入流對象中的方法read/readLine,讀取文本。
        String line;
        while ((line = br.readLine()) != null) {
            // 當每行數據都讀取了后,如果再讀取,則會返回null
            System.out.println(line);
        }
    }
}

文件test.txt內容如下:

img

控制台輸出:

第1行數據
第2行數據
第3行數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM