【Java學習筆記(一百一十五)】之 檔案,文字輸入輸出流,字元編碼方式
本文章由公號【開發小鴿】釋出!歡迎關注!!!
老規矩–妹妹鎮樓:
一. 輸入與輸出
(一) 輸入流 / 輸出流
從其中讀入一個位元組序列的物件稱為輸入流,而可以向其中寫入一個位元組序列的物件稱為輸出流。這些位元組序列的來源可以是檔案,網路連線和記憶體塊。抽象類InputStream和OutputStream構成了IO類層次結構的基礎,但是面向位元組的流無法處理Unicode形式的資訊(每個Unicode字元使用了多個位元組表示),所以從抽象類Reader和Writer中繼承出來了用於處理Unicode字元的單獨的類層次結構,這些類都是基於兩個位元組的Char值的。當然還有其他在處理位元組基礎上的更上層的類,如處理二進位制的類DataInputStream, DataOutputStream,處理zip壓縮檔案的ZipInputStream, ZipOutputStream類等等。
(二) InputStream類
1. read()
抽象方法read(),讀入一個位元組,返回讀入的位元組,在遇到結尾時返回-1。在設計具體的輸入流類時,需要覆蓋這個方法來提供適當的功能,執行時都會阻塞,直到位元組真正被讀入。
2. read(byte[] b)
讀入一個位元組陣列,返回實際讀入的位元組數。
3. transferTo(OutputStream out)
將當前輸入流中的所有位元組傳送到指定的輸出流中,返回傳遞的位元組數。
4. available()
在不阻塞的情況下可獲取的位元組數,可以用於檢查當前可讀入的位元組數量,便於進行之後的操作。
5. close()
關閉這個輸入流,釋放作業系統資源。
6. mark(int readlimit)
在輸入流的當前位置打上標記。
7. reset()
返回最後一個標記,隨後對read的呼叫將重新讀入這些位元組。
(三) OutputStream
1. write(int n)
抽象類,寫出一個位元組的資料。
2. close()
沖刷用於該輸出流的緩衝區,並且關閉該輸出流,所有被臨時置於緩衝區中,以便用更大的包的形式傳遞的位元組都會在關閉輸出流的時候被送出,如果不關閉輸出流,那麼寫出位元組的最後一個包可能永遠不會傳遞。
3. flush()
沖刷輸出流,即將緩衝區的資料送出。
(四) 檔案輸入輸出流
FileInputStream 和 FileOutputStream可以提供附著在磁碟檔案上的輸入流和輸出流,只需要向構造器提供檔名或檔案的完整路徑名。如下所示:
var fin = new FileInputStream(“a.txt”);
所有java.io中的類都將相對路徑名解釋為以使用者工作目錄開始,且由於反斜槓“\”在Java字串中是轉義字元,所以在Windows風格的路徑名中使用“\”,如C:\Windows\win.ini。
(五) 組合過濾器
對於不同的輸入流,可以巢狀在一起使用以獲得更加強大靈活的功能,如從一個檔案中讀取輸入流,並且通過緩衝機制讀取,最後通過轉換為二進位制,就可以用以下的方式:
var din = new DataInputStream(new BufferedInputStream( new FileInputStream(“a.txt”)));
這種複雜的構造器序列可以靈活地將不同的輸入流組合在一起,非常強大。
如預覽下一個位元組是否是期望的值,如果不是,將其推回到流中:
var pbin = new PushbackInputStream(new BufferedInputStream( new FileInputStream(“a.txt”)));
int b = pbin.read();
if( b != ‘<’) pbin.unread(b);
(六) 文字輸入輸出
文字格式的IO適合人類閱讀,在儲存文字字串時,需要考慮字元編碼方式,OutputStreamWriter類將使用選定的字元編碼方式,把Unocide碼元的輸出流轉換為位元組流,UTF-8是網際網路上最常用的編碼方式。如從控制檯讀入鍵盤敲擊資訊,並轉換為Unicode:
var int = new InputStreamReader(System.in);
或指定編碼方式:
var in = new InputStreamReader(new FileInputStream(“data.txt”, StandardCharsets.UTF_8));
對於文字輸出,可以使用PrintWriter,與System.out相同的print, println, prinf等方法,即用文字輸出到檔案中,如下所示:
var out = new PrintWriter(“employee.txt”, StandardCharsets.UTF_8);
也可以巢狀輸出使用:
var out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(“employee.txt”, StandardCharsets.UTF_8), true));
最簡單的處理文字的方式就是使用Scanner類,我們可以從任何輸入流中構建Scanner物件,掃描一行行進來。
(七) 字元編碼方式
Java針對字元使用的是Unicode標準,每個字元或者“編碼點”都具有一個21位的整數,有多種不同的字元編碼方式,UTF-8將每個Unocide編碼點編碼為1到4個位元組的序列,包含了英語中用到的所有字元的ASICC字符集中的每個字元都只會佔用一個位元組,UTF-8會將每個Unicode編碼點編碼為1個或2個16位值,需要考慮高位低位的優先順序,可以在檔案的開頭來表示使用的是哪一種格式。