Java -- 流與檔案01
阿新 • • 發佈:2018-12-28
流
Java中用於輸入和輸出的各種應用程式設計介面(Application Programming Interface, API)。在Java API中,可以在其中讀入一個位元組序列的物件稱做輸入流,而可以向其中寫入一個位元組序列的物件稱做輸出流。這些位元組序列的來源地和目的地可以是檔案,而且通常是檔案,但是也可以是網路連線,甚至是記憶體塊。抽象類InputStream和OutputStream構成了輸入/輸出(I/O)類層次結構的基礎。因為面向位元組的流不便於處理以Unicode形式儲存的資訊,Unicode中每個字元都使用了多個位元組來表示,所以從抽象類Reader和Writer中繼承出來了一個專門用於處理Unicode字元的單獨的類層次結構。這些類都是基於兩位元組的Unicode碼元,而不是基於單位元組的字元。
讀寫位元組
OutputStream類定義了下面的抽象方法,abstract void write(int b),它可以向某個輸出位置寫出一個位元組。
read和write方法在執行時都將阻塞,直至位元組確實被讀入或寫出。 available方法檢查當前可讀入的位元組數量。但完成了對流的讀寫,應該呼叫close方法來關閉它,這個呼叫會釋放掉有限的作業系統資源,如果一個應用程式打開了過多的流而沒有關閉,那麼系統資源將被耗盡。關閉一個輸入流同時會沖刷用於該輸出流的緩衝區。Java提供了眾多從基本的InputStream和OutputStream類匯出的類,這些類使我們可以處理那些以常用格式表示的資料,而不是位元組。
完整的流家族
組合流過濾器
FileInputStream和FileOutputStream可以提供附著在一個磁碟檔案上的輸入流和輸出流,而你只需向其構造器提供檔名或檔案的完整路徑名。所有的java.io中的類都將相對路徑解釋為以使用者工作目錄開始。可以通過呼叫System.getProperty("user.dir")來獲得這個資訊。windows系統下,可以使用單斜槓字元,由於反斜槓字元在Java中是轉義字元,所以要用雙反斜槓。而對於可移植的程式來說,應該使用程式所執行平臺的檔案分隔符,我們可以通過常量字串java.io.File.separator來獲得它。Java提供了一種靈巧的機制。某些流(例如FileInputStream和由URL類的openStream方法返回的輸入流)可以從檔案和其他更外部的位置上獲得位元組。而其他的流(例如DataInputStream和PrintWriter)可以將位元組組裝到更有用的資料型別。如:
/*從檔案中讀入數字*/ FileInputStream fin = new FileInputStream("employee.dat"); DataInputStream din = new DataInputStream(fin); double s = din.readDouble();
可以通過巢狀過濾器來新增多重功能,例如,流在預設情況下是不被緩衝池快取的,即每個對read的呼叫都會請求作業系統再分發一個位元組。使用緩衝機制顯得更高效,如用於檔案的資料輸入方法:
DataInputStream din = new DataInputStream(
new BufferedInputStream(
new FileInputStream("employee.dat")));
有時當多個流連結在一起時,需要跟蹤各個中介流。 如:當讀入輸入時,需要瀏覽下一個位元組,以瞭解它是否是想要的值。Java提供了PushbackInputStream:
PushbackInputStream pbin = new PushbackInputStream(
new BufferedInputStream(
new FileInputStream("employee.dat")));
/*預讀下一個位元組*/
int b = pbin.read();
/*在它並非你所期望的值時將其推回流中*/
if(b != '<') pbin.unread(b);
/*讀入和回推是可回推輸入流的僅有方法,如想預先瀏覽並且可以讀入數字,那麼就需要一個
既是可回推輸入流,又是一個數據輸入流的引用*/
DataInputStream din = new DataInputStream(
pbin = new PushbackInputStream(
new BufferedInputStream(
new FileInputStream("employee.dat"))));
文字輸入與輸出
在儲存資料時,可以選擇二進位制格式或文字格式。OutputStreamWriter類將使用選定的字元編碼方式,把Unicode字元流轉換為位元組流。而InputStreamReader類將包含位元組(用某種字元編碼方式表示的字元)的輸入流轉換為可以產生Unicode碼元的讀入器。 如讓一個輸入讀入器可以從控制檯讀入鍵盤敲擊資訊: InputStreamReader in = new InputStreamReader(System.in);如何寫出文字輸出
對於文字輸出,可以使用PrintWriter。這個類擁有以文字格式列印字串和數字的方法,甚至有一個將PrintWriter連結到FileWriter的便捷方法。 PrintWriter out = new PrintWriter("employee.txt"); 等價於 PrintWriter out = new PrintWriter(new FileWriter("employee.txt"));為了輸入到列印寫出器,需要使用與使用System.out相同的print, println和printf方法。
String name = "Harry Hacker";
double salary = 75000;
out.print(name);
out.print(' ');
out.println(salary);
/*將Harry Hacker 75000.0 輸入到 寫入器 out中。之後這些字元被轉換為位元組並最終寫入employee.txt中*/
如果寫出器設定為自動沖刷模式,那麼只要println被呼叫,緩衝區中的所有字元都會被髮送到它們的目的地。預設情況下,自動沖刷機制是禁用的。可以通過呼叫PrintWriter(Writer out, Boolean autoFlush)來啟用或禁用自動沖刷機制。
如何讀入文字輸入
在Java5.0之前,處理文字輸入的唯一方式是通過BufferedReader類,它擁有一個readLine方法,使得可以讀入一行字元。BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream("employee.txt"), "UTF-8"));
然而,BufferedReader沒有任何用於讀入數字的方法,所以我們使用Scanner來讀入文字輸入。