Java-IO流之BufferedReader 和BufferedWriter的使用和原理


BufferedReader和BufferedWriter出現的目的是為了對FileReader以及FileWriter的讀寫操作進行增強,而怎么增強呢,原理類似於使用StringBuilder,是把數據先放入他們的一個char數組中,然后再操作char數組。

使用緩沖區的字符流是使用了裝飾着模式對FileReader等進行功能上的增強,裝飾者模式與繼承都可以實現功能上的增強,但是裝飾者可以做得更加的靈活,也不會使繼承樹變得太過復雜。

 

以下是BufferedWriter源碼的一小部分

public class BufferedReader extends Reader {

    private Reader in;  構造函數需要用到的Reader

    private char cb[];   自己的char數組,它本身的read()方法將是訪問這個數組,這個數組就是緩沖區
    private int nChars, nextChar;     char數組位置和數量的索引

接下來看一下BufferedWriter源碼的read()方法:

    public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            for (;;) {
                if (nextChar >= nChars) {
                    fill();
                    if (nextChar >= nChars)
                        return -1;
                }
                if (skipLF) {
                    skipLF = false;
                    if (cb[nextChar] == '\n') {
                        nextChar++;
                        continue;
                    }
                }
                return cb[nextChar++];
            }
        }
    }

這個read()方法是訪問的BufferedReader本身的char數組,當發現數組的元素已經被訪問完畢就調用fill()方法重新填充char數組。這個就是使用緩沖區的字符流的實質。

同樣的,BufferedWriter也是先把數據寫入自身的char數組中,刷新的時候再寫入文件。

注意:

1、當使用BufferedWriter或者是BufferedReader的時候,是把FileReader的賦給了BufferedReader里面的Reader對象,所以要保存數據到文件的時候調用傳入BufferedReader的參數Reader是無效的,需要使用BufferedReader進行刷新或者關BufferedReader之后數據才會保存到文件;

2、當關閉BufferedReader的時候,傳入作為參數的reader也會跟着關閉。

3、BufferedReader具有一個特殊的方法readerLine(),功能是讀取一行,原理是從char數組中讀取,判斷是否遇到換行符,是的話返回。

 

下面有根據傳智播客的IO視頻自己寫的一個BufferedReader代碼:

public class MyBufferedReader {

    private Reader reader;

    private int count;
    private int position;
    private char[] contentArray = new char[1024];
    private int ch;

    private final String LINE_SEPARATE = System.getProperty("line.separate");

    public MyBufferedReader(Reader reader) {
        this.reader = reader;
    }


    public int myReader() throws IOException {
        if (count == 0) {
            count = reader.read(contentArray);
            position = 0;
        }

        if (count == -1) {
            return -1;
        }

        count--;
        ch = contentArray[position];
        position++;

        return ch;
    }

    public String myReadLine() throws IOException {
        StringBuilder sb = new StringBuilder(256);
        int ch = 0;
        while ((ch = myReader()) != -1) {
            if (ch == '\r') {
                continue;
            }

            if ((char) ch == '\n') {
                return sb.toString();
            }

            sb.append((char) ch);
        }

        if (sb.length() > 0)
            return sb.toString();

        return null;
    }

    public void close() throws IOException {
        reader.close();
    }

}

  這里是調用的代碼:

        try (FileWriter fileWriter = new FileWriter("buffer.txt")) {
            try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
                int count = 3;

                while (count != 0) {
                    bufferedWriter.write("123456");
                    bufferedWriter.newLine();
                    bufferedWriter.write("abcdef");
                    bufferedWriter.newLine();
                    count--;
                }
            }
        }

        try (FileReader fileReader = new FileReader("buffer.txt")) {
            MyBufferedReader bufferedReader = new MyBufferedReader(fileReader);
            String line = null;
            while ((line = bufferedReader.myReadLine()) != null) {
                System.out.println(line);
            }
        }

  運行結果為:

Disconnected from the target VM, address: '127.0.0.1:26416', transport: 'socket'
123456
abcdef
123456
abcdef
123456
abcdef

Process finished with exit code 0

  

 


免責聲明!

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



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