BufferedReader in = new BufferedReader(new FileReader("foo.in"));
will buffer the input from the specified file. Without buffering, each
invocation of read() or readLine() could cause bytes to be read from
the file, converted into characters, and then returned, which can be
very inefficient.
这段话怎么理解,如果使用了缓冲区就不会涉及到byte转character?
求两个读取文件的流程和效率对比,先行谢过了。
沒有緩衝區時,每次讀取操作都會導致一次檔案讀取操作(就是告訴作業系統核心我要讀這個檔案的這個部分,麻煩你幫我把它取過來) 。而有緩衝區時,會一次讀取很多數據,然後再依要求分次交給上層呼叫者。讀取區塊大小通常是以最適合硬體的大小來讀的,因為對於硬體來說,一次讀取一塊連續資料(例如1K)和一次讀取一個位元組需要的時間幾乎是一樣的(都是一次讀取操作,只是最終提交的資料量有差異)。帶緩衝的 I/O 和不帶緩衝的相比效率差異是非常顯著的,你可以自行寫程式測試。
樓上的解釋很好. 我做一點補充:
說到java reader快取, 其實有兩層快取:
1. OS快取, 把磁碟資料 讀入記憶體, 透過read ahead, io scheduler等減少磁碟讀取次數.
2. App快取, 做快取/預讀, 即BufferredReader的角色.
BufferredReader的作用, 我的理解, 一) 減少System Call次數; 二) 減少磁碟讀取次數.
我記得很久以前寫過一個內部使用Byte數組的BufferedStreamReader,實測效率比原本使用Char數組的要快,不過這只是在32位元系統下測試的。寫這個StreamReader是為了修正檔案上傳元件裡原本的效率問題。
實際上BufferedReader和StreamReader(例如FileReader就是一個StreamReader)的用途是不同的,流(Stream)資料就應該用byte數組來取得最大效率。而BufferedReader的作用並不是讀取一堆流式數據,而是針對帶有換行符的文本內容的按行讀取,同時要正確處理各種字符集的文本數據。
明白BufferedReader的真正用途就很容易理解,為何內部使用Char數組,因為Java的字元和字串都是雙位元組的,以解決多種字元集的問題。
BufferedReader一般建立時需要一個StreamReader的參數,由StreamReader去用流的方式讀取資料。而BufferedReader只是解析流資料並組成一行一行的String。
因此,BufferedReader的Buffer也是具有非常重要的用途,按字符集解析流數據,組成Char數組,這個過程一定是需要預先讀取的。接著才是基於Buffer,辨析Windows和Linux不同換行符nr,解析出一行String回傳。
用了Buffer當然還是需要從Byte到Char的轉換,只不過比之不用Buffer,效率會有數量級的提升。