1. 程式人生 > >IO流學習筆記(一)之FileWriter與FileReader

IO流學習筆記(一)之FileWriter與FileReader

IO流用來處理裝置之間的資料傳輸
Java對資料的操作是通過流的方式
Java用於操作流的物件都在IO包中
流按照操作資料分為兩種:位元組流和字元流
流按流向分為:輸入流和輸出流

輸入流和輸出流是相對於記憶體裝置而言
因為記憶體速度快,程式在記憶體中執行,資料從外設(硬碟)讀取到記憶體中為輸入,資料由記憶體到外設(硬碟)為輸出

字元流的由來:
位元組流可以處理所有資料,最早是沒有字元流的,但是由於不同語言產生了多張碼錶(用於將其語言轉為計算機語言即01碼,如ascll,GBK等),由於多張碼錶的麻煩,國際組織便產生一張通用的碼錶Unicode碼錶,可以識別中英文等,Java中內建Unicode碼錶。其特點是無論什麼字元都用兩個位元組表示,導致同一個中文在GBK和Unicode碼錶中對應的數字結果不同(因為對於編寫程式選擇不同編碼方式會產生亂碼),將(位元組流+編碼表)的組合方式封裝為字元流。


簡要來說:位元組流讀取文字位元組資料後,不直接操作,而是先查指定的編碼表,獲取對應的文字,再對這個文字進行操作。簡單來說,就是位元組流+編碼表。

分類
位元組流的抽象基類:InputStream,OutputStream
字元流的抽象基類:Reader,Writer
注:由這四個類派生出來的子類名稱都是以其父類名作為子類名的字尾,如InputStream的子類FileInputStream,Reader的子類FileReader
命名方式可以看作:該物件的功能+以父類名作為字尾

操作文字資料建議優先考慮字元流,而且要將資料從記憶體寫到硬碟上,要使用字元流中的輸出流Writer類,將資料從記憶體寫到硬碟上,硬碟上的資料基本體現是檔案,希望找到一個可以操作檔案的Writer,即FileWriter

既然是往一個檔案中寫入文字資料,那麼在建立物件時,必須明確該檔案(用於儲存資料的目的地),如果檔案不存在,則會自動建立;如果檔案存在,則會被覆蓋,由於檔案路徑可能是非法路徑,會導致IO異常,因此在方法處丟擲,即throws IOException

建構函式

FileWriter(String fileName):根據給定的檔名構造一個FileWriter物件

FileWriter(String fileName,boolean append):根據給定的檔名以及指示是否附加(續寫)寫入資料的boolean值來構造FileWriter物件,建構函式中加入true,可以實現對檔案進行續寫,不然第二次執行程式會刪除原有內容,續寫,即可以再次執行寫入時,是在原有的基礎上基礎寫入,原內容是儲存的

flush()與close()區別:
flush()方法:重新整理該流的緩衝,如果該流已儲存緩衝區中各種write()方法的所有字元,則立即將它們寫入預期目標。然後,
如果該目標是另一個字元或位元組流,則將其重新整理。因此,一次flush()呼叫將重新整理Writer和OutputStream鏈中的所有緩衝區,因此上述寫入也可以:

close()關閉流,關閉資源。在關閉前會先呼叫flush重新整理緩衝中的資料到目的地

與flush()的區別:flush可以使用多次,不斷寫入不斷重新整理即可,而close只可以使用一次,關閉之後,不可以進行流操作。 形象比喻:在一個文件中寫資料,每儲存一次就相當於進行一次flush(不儲存並沒有寫入硬碟);如果一直寫不儲存,寫完之後關閉,進行一次儲存,寫入硬碟,相當於close,再開啟檔案操作時,是另一個流。

換行問題

並不能實現換行,windows中的換行是\r,unix中換行是\n,因此需要,還有一種與系統無關的換行方式:

進行讀取有兩種方式,一種是read()方法,一種是read(char[] cbuf)方法,如下將分別介紹兩種方法:

public int read() throws IOException:
讀取單個字元,在字元可用,發生I/O錯誤或者已到達流的末尾前,此方法一直阻塞
返回:作為整數讀取的字元,範圍在0到65535之間,如果已到達流的末尾,則返回-1

執行結果:

這裡寫圖片描述

原理:
這裡寫圖片描述

基於如上原理可以如下進行連續讀取,即連續讀取資料的第一種方式,一次讀一個

public int read(char[] cbuf) throws IOException:
將字元讀入陣列。在某個輸入可用,發生I/O錯誤或者已到達流的末尾前,此方法一直阻塞
引數:
cbuf-目標緩衝區
返回:
讀取的字元數(不同於read()方法,read()方法返回的是讀到的字元),商務英語前景如果已到達流的末尾,則返回-1
不同於read(),read(char[] cbuf)是每讀取一個便將其存與陣列cbuf中

這裡寫圖片描述

原理:

這裡寫圖片描述

基於第二種讀取方式的連續讀取:

兩種讀取方式哪種好?

第二種讀取所需的迴圈次數少,效率高,第一種方式有多少個字元就需要迴圈多少次

兩個流(輸入流fr與輸出流fw)原本是沒有關係的,想要使兩者能夠進行資料傳輸,需要通過一個“中轉”即上述的陣列容器

這裡寫圖片描述