標籤:構造 www 等於 link 輸出資料流 接收 比較 ges 限制
轉載請註明源出處:http://www.cnblogs.com/lighten/p/7074488.html
1.前言
按照位元組流的順序一樣,字元流也提供了緩衝字元流,與位元組流不同,Java雖然提供了FilterReader和FilterWriter類,但是緩衝字元流沒有繼承者兩個類,而是直接繼承了Reader和Writer類。
2.BufferedReader
建構函式接受一個Reader和一個緩衝字元數量,預設8192。
read方法不但使用了同步鎖,還採取了for(;;)形式。nextChar是要讀取的字元位置下標,nChars是當前緩衝中字元數量。很顯然,要讀取的字元下標大於等於當前存在的字元,意味著緩衝中的字元已經被讀取完了,需要重新擷取寫入緩衝。這個就是fill()方法。fill()之後還是沒有,就意味著讀取完了,返回-1。skipLF是否跳過換號符,預設false。然後就是返回位置為nextChar的cb字元數組的字元,自增1。
fill()方法需要考慮到mark方法產生的標記,有標記和無標記的情況是不同的,無標記的時候肯定就是buffer被使用完了,從0開始重新填資料。也就是最後一段了。有標記的時候就不能捨棄標記的資料了,所有需要計算dst的值,由於存在readAheanLimit參數所以mark的計算又有區別。這個參數的意思是重設標記的時候,之前讀取過的資料最多出現多少。因此,fill方法計算了標記位到已讀取完的長度,如果大於這個限制,這就是一個無效的標記(標記在1號位,讀完到5號位,但只能出現兩個曆史字元readAheanLimit,這樣標記位就沒有用了,因為不能刪除後面多餘的字元吧,所以是一個標記)。有效標記又分為兩種情況,一種是readAheanLimit小於當前緩衝大小,這個就不要緊,拷貝從標記為開始的資料就可以了。標記為置為0,新資料要從delta開始寫了。如果大於緩衝,肯定就是重新建立緩衝了。
read字元數組的方法也是一個常見的處理過程了,先執行一次,如果都完了就直接返回了,如果沒讀完,且沒有讀到需要的數量就通過while迴圈不斷讀,讀完了流就直接break,或者讀到所需的len長度。
如果沒有可讀的緩衝了當然要重新fill,但是這裡也有一種情況,就是所要的長度超過緩衝大小,這個時候就直接從原來的流中讀取返回。重填了之後還是沒有,就是讀取完了,返回-1。後面就是把資料填充到給的字元數組了,可能緩衝區的資料不夠,所以是選擇了小的那個值,然後返回。
其它的方法沒上面好講的了。最後的一個lines方法,是JDK8才提供的,具體實現超過IO的範疇,作用是返回一個Stream<String>,裡面就是所讀取的流的一行行,懶載入的方式。
3.BufferedWriter
相比於BufferedReader,輸出資料流BufferWriter較簡單些。
一樣接收一個Writer和緩衝大小,預設也是8192個字元。
write方法,如果緩衝寫滿了就刷入持有的writer。然後重設nextChar為0,寫入當前的這個位置。
裡面自己寫了一個比較方法,而沒有使用Math類的方法,理由上面也給了,使用完了檔案描述符的時候,會嘗試列印堆疊追蹤。
其它兩個write方法都比較簡單,思路一樣,就不再繼續介紹了。
Java之IO(十一)BufferedReader和BufferedWriter