1. 程式人生 > >java 字元緩衝流BufferedReader和BufferedWriter

java 字元緩衝流BufferedReader和BufferedWriter

本節概要:

目錄

BufferedReader

BufferedWriter

字元緩衝流複製文字檔案:


BufferedReader

繼承自Reader

構造方法:

     private static int defaultCharBufferSize = 8192;
//可以手動設定快取去char陣列的大小
     public BufferedReader(Reader in, int sz) {
        super(in);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.in = in;
        cb = new char[sz];
        nextChar = nChars = 0;
    }
    //建立一個char陣列,大小為8192,用來快取
    public BufferedReader(Reader in) {
        this(in, defaultCharBufferSize);
    }

工作過程:使用BufferedReader時,先從Reader物件(FileReader)中讀取資料寫入到char[],然後從 自身的char陣列中訪問資料,當char陣列的資料被訪問完畢,就呼叫fill()方法重新填充char陣列。關閉BufferedReader時,其構造引數的Reader也被關閉

特有方法:

String readLine() 從BufferedReader自身的char陣列中讀取一行文字,遇到以下字元會認為完成一行的讀取,換行('\n'),回車('\r')或者回車後直接換行,返回包含該行內容的字串,如果達到流末尾,返回null

看下BufferedReader的read方法:read()訪問的BufferedReader本身的char陣列,當陣列的內容被訪問完畢時呼叫呼叫fill()方法重新填充char陣列。

   private Reader in;
   public int read(char cbuf[], int off, int len) throws IOException {
            synchronized (lock) {
            ensureOpen();
            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
                ((off + len) > cbuf.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }

            int n = read1(cbuf, off, len);
            if (n <= 0) return n;
            while ((n < len) && in.ready()) {
                int n1 = read1(cbuf, off + n, len - n);
                if (n1 <= 0) break;
                n += n1;
            }
            return n; 
   private int read1(char[] cbuf, int off, int len) throws IOException {
          if (nextChar >= nChars) {
            if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
                return in.read(cbuf, off, len);
            }
            fill();
        }
        if (nextChar >= nChars) return -1;
        if (skipLF) {
            skipLF = false;
            if (cb[nextChar] == '\n') {
                nextChar++;
                if (nextChar >= nChars)
                    fill();
                if (nextChar >= nChars)
                    return -1;
            }
        }
        int n = Math.min(len, nChars - nextChar);
        System.arraycopy(cb, nextChar, cbuf, off, n);
        nextChar += n;
        return n;
    }

BufferedReader示例:

原始檔word.txt內容:
好啊
你好
天天
///////////////////////////////////////////////////////////////
import java.io.*;

public class BufferedReaderTest01 {
    public static void main(String[] args){
        try (
                BufferedReader br =new BufferedReader(new FileReader("word.txt"));
                ){
            String s;
            //每次讀取一行,讀到末尾處為null
            while ((s=br.readLine())!=null){
                System.out.println( s);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
out:
好啊
你好
天天

BufferedWriter

繼承自Writer

構造方法:

 private static int defaultCharBufferSize = 8192;
//建立預設8192大小的char陣列,用來快取
 public BufferedWriter(Writer out) {
        this(out, defaultCharBufferSize);
    }
//根據指定大小建立char陣列,用來快取
 public BufferedWriter(Writer out, int sz) {
        super(out);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.out = out;
        cb = new char[sz];
        nChars = sz;
        nextChar = 0;
    }

工作工程: BufferedWriter先將資料寫入自身的char陣列,當呼叫write方法時,將內容寫到自身的char陣列,再呼叫引數Writer物件的write方法從char陣列中讀取內容寫入到檔案中

關閉BufferedWriter時,自動關閉作為引數的Writer物件

特有方法:

newLine()換行

write方法,可以寫字串和char陣列,可以指定他們的起始位置和長度,看下write的原始碼:

先將內容儲存到自身的char陣列中,再訪問自身char陣列,再將內容寫入到檔案中

private Writer out;//構造方法中傳入的Writer物件
private char cb[];
//呼叫flushBuffer方法來寫
public void write(int c) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (nextChar >= nChars)
                flushBuffer();
            cb[nextChar++] = (char) c;
        }
    }
//呼叫out的write方法,out是建立BufferedWriter物件時,傳進來的Writer物件
void flushBuffer() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (nextChar == 0)
                return;
            out.write(cb, 0, nextChar);
            nextChar = 0;
        }
    }

示例:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterTest01 {
    public static void main(String[] args){
        try (
                BufferedWriter bw=new BufferedWriter(new FileWriter("test\\test6.txt"));
                ){
            bw.write("我們要加油");
            bw.newLine();//換行
            char [] charArr={'我','們','熱','愛','祖','國'};
            bw.write(charArr,0,4);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
out:
test6.txt的內容為:
我們要加油
我們熱愛

字元緩衝流複製文字檔案:

import java.io.*;

public class FileCopy02 {
    public static void main(String[] args){
        try (
                BufferedReader br=new BufferedReader(new FileReader("word1.txt"));
                BufferedWriter bw=new BufferedWriter(new FileWriter("test\\test7.txt"));
                ){
            String s;
            //通過每次讀取一行,提高效率
            while((s=br.readLine())!=null){
                bw.write(s);
                bw.newLine();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
out:
原始檔word1.txt內容:
好嗎
天天
目標檔案test7.txt內容:
好嗎
天天

畫個示意圖: