1. 程式人生 > >學習記錄(探究java i/o)

學習記錄(探究java i/o)

輸入/輸出:探究java.io 本章將介紹打包在java.io中的基於流的I/O系統,它們自Java最初發布以來就已提供且被廣泛使 用從1.4版本開始,java新增量另一套I/O系統,被稱為NIO(也就是新I/O)NIO被打包到java.nio 及其子包中。
1 I/O類和介面 (見截圖)
2 File 類 儘管java.io定義的大多數類用於操作流,但File不是。File類直接處理檔案和檔案系統。 也就是說,File類沒有指定如何從檔案檢索資訊以及如何向文中儲存資訊,而是描述了檔案 本身的屬性。 File物件用於獲取和操作與磁碟檔案相關的資訊,例如許可權、時間、日期以及目錄路徑,並且還可以瀏覽子目錄層次。 注意:Path介面和Files類是NIO系統的一部分,在許多情況下都為File類提供了強大的替換方案。
File的建構函式(4種) 注意:在Windows版本的java中使用正斜槓(/),那麼路徑仍然會被正確解析。 如果使用windows約定的反斜槓(\),那麼在字串中需要使用轉義字元序列(\\)。 Java使用介於unix和windows約定之間的路徑分隔符。
File類中定義了獲取File物件中標準屬性的方法。例如: getName()方法返回檔案的名稱; getParent()方法返回父目錄名; 如果檔案存在,exists()返回true,否則返回false。
2.1 目錄 String[] list();
2.2 使用FilenameFilter介面 使返回結果只包含匹配特定檔名模式的那些檔案。可以使用list()的第二種形式: String[] list(FilenameFilter FFObj) 其中FFObj是實現了FilenameFilter介面的類的物件。 FilenameFilter介面只定義了方法accept(),該方法針對列表中的每個檔案呼叫一次,一般形式 如下: boolean accept(File directory,String filename)
2.3 listFiles()方法 File[] listFiles() File[] listFiles(FilenameFilter FFObj) File[] listFiles(FileFilter FObj)
3 AutoCloseable、Closeable和Flushable介面 ..AutoColseable介面只定義了close()方法: void close() throws Exception ..Closeable介面也定義了close()方法。實現了Closeable介面的類的物件可以被關閉。 從JDK7開始,Closeable擴充套件了AutoCloseable。因此,所有實現了Closeable介面的類 也都實現了AutoCloseable介面。 ..實現了Flushable介面的類的物件,可以強制將緩衝的輸出寫入與物件關聯的流中。 該介面定義了flush()方法,如下: void flush() throws IOException 重新整理流通常會導致緩衝的輸出被物理地寫入底層裝置中。寫入流的所有I/O類都實現了 Flushable介面。
4 I/O異常 如果發生I/O錯誤,就會丟擲IOException異常。 如果檔案無法開啟,會丟擲FileNotFoundException異常。 FileNotFoundException異常是IOException的子類。
5 關閉流的兩種方式 第一種是顯式地在流上呼叫close()方法 第二種是使用jdk7新新增的帶資源的try語句,從而自動執行這一過程。 ..關於帶資源的try語句的3個關鍵點: 1.由帶資源的try語句管理的資源必須是實現了AutoCloseable介面的類的物件。 2.在try程式碼中宣告的資源被隱式宣告為final。 3.通過使用分號分隔每個宣告可以管理多個資源。 出自之外:所宣告的資源的作用域被限制在帶資源的try語句中。
6 流類 當操作字元或字串時,應當使用字元流;當操作位元組或其他二進位制物件時,使用位元組流。
7 位元組流 位元組流為處理面向位元組的I/O提供了豐富的環境。位元組流可以用於任意型別的物件,包括二進位制 資料。 InputStream和OutputStream位於位元組路的頂層。
7.1 InputStream類 InputStream是抽象類,定義了Java的流位元組輸入模型,並且還實現了AutoCloseable和 Closeable介面。當發生I/O錯誤時,該類中的大部分方法都會丟擲IOExeption異常(mark()和 markSupported()除外)。
7.2 OutputStream類 OutputStream是定義流位元組輸出的抽象類,實現了AutoCloseable、Closeable以及Flushable 介面。該類中的大部分方法都返回void,並且如果發生I/O錯誤,大部分方法會丟擲 IOException異常。
7.3 FileInputStream類 使用FileInputStream類建立的InputStream物件可以用於從檔案讀取位元組。兩個常用的構造函 數如下所示: FileInputStream(String filePath) FileInputStream(File fileObj) 這兩個建構函式都會丟擲FileNotFoundException異常。其中,filePath是檔案的完整路徑名, fileObj是描述檔案的File物件。
7.4 FileOutputStream類 FileOutputStream類建立能夠用於向檔案中寫入位元組的OutputStream物件。 該類實現了AutoCloseable、Closeable以及Flushable介面。
7.5 ByteArrayInputStream類 ByteArrayInputStream是使用位元組陣列作為源的輸入流的一個實現。 兩個建構函式: ByteArrayInputStream(byte[] array) ByteArrayInputStream(byte[] array,int start,int numBytes)
7.6 ByteArrayOutputStream類 ByteArrayOutputStream是使用位元組陣列作為目標的輸出流的一個實現。 建構函式: ByteArrayOutputStream() ByteArrayOutputStream(int numBytes) 在第一種形式中,建立一個32位元組的緩衝區。 在第二種形式中,建立一個由numBytes指定大小的緩衝區。 緩衝區被儲存在ByteArrayOutputStream中受保護的buf域變數中。 如果需要的話,緩衝區的大小會自動增加。 緩衝區能夠儲存的位元組數量包含在ByteArrayOutputStream中受保護的count域變數中。 close()方法對ByteArrayOutputStream物件沒有效果。所以,不需要為ByteArrayOutputStream 物件呼叫close()方法。如果呼叫的話也不會產生錯誤。
7.7 過濾的位元組流 過濾的位元組流是簡單的封裝器,用於封裝底層的輸入流或輸出流,並且還透明地提供一些擴充套件 級別地功能。這些流一般是通過接收通用流地方法訪問地,通用流是過濾流地超類。 典型的擴充套件是緩衝、字元轉換以及原始資料轉換。過濾的位元組流類是FilterInputStream和 FilterOutputStream,他們的建構函式如下所示: FilterOutputStream(OutputStream os) FilterInputStream(InputStream is) 這兩個類提供的方法與InputStream和OutputStream類中的方法相同。
7.8 緩衝的位元組流 對於面向位元組的流,緩衝流通過將記憶體緩衝區附加到I/O系統來擴充套件過濾流。 這種流允許Java一次對多個位元組執行多次I/O操作,從而提升效能。 因為可以使用緩衝區,所以略過、標記或重置流都是可能發生的。 緩衝的位元組流類是BufferedInputStream和BufferedOutputStream。 PushbackInputStream也實現了緩衝流。
7.8.1 BufferedInputStream類 緩衝I/O是很常見的效能優化手段。Java的BufferedInputStream類允許將任何InputStream 物件封裝到緩衝流中以提高效能。 BufferedInputStream類有兩個建構函式: BufferedInputStream(InputStream inputStream) BufferedInputStream(InputStream inputStream,int bufSize)
使緩衝區大小等於記憶體頁面、磁碟塊等大小的整數倍,可以明顯提高效能。 但這依賴於具體實現。 最優的緩衝區大小通常以來於宿主作業系統、可用的記憶體量以及機器的配置。 比較好的緩衝區大小大約是8192位元組,並且對於I/O系統來說即使附加比較小的緩衝區,也 總是一個好主意。
除了任何InputStream都實現了的read()和skip()方法外,BufferedInputStream還支援mark()和reset()方法。
7.8.2 BufferedOutputStream類 除了增加了flush()方法之外,BufferedOutputStream與所有OutputStream類似, flush()方法用於確保將資料緩衝區寫入被緩衝的流中。 BufferedOutputStream是通過減少系統實際寫資料的次數來提高效能的,因此可能需要呼叫 flush()方法,從而要求立即寫入緩衝區的所有資料。 ..與緩衝輸入不同,緩衝輸出沒有提供附加功能。Java中用於輸出的緩衝區只是為了 提高效能。下面是兩個建構函式: BufferedOutputStream(OutputStream outputStream) BufferedOutputStream(OutputStream outputStream,int bufSize) 第一種形式使用預設緩衝區大小建立緩衝流。在第二種形式中,緩衝區是由bufSize傳遞的。
7.8.3 PushbackInputStream類 緩衝區的新應用之一就是回推(pushback)的實現。回推用於輸入流,以允許讀取位元組,然後 再將他們返回(回推)到流中。PushbackInputStream類實現了這一思想,提供了一種機制, 可以“偷窺”來自輸入流的內容而不對他們進行破壞。建構函式如下: PushbackInputStream(InputStream inputStream) PushbackInputStream(InputStream inputStream,int numBytes) 第一種形式建立的流物件允許將一個位元組返回到輸入流; 第二種形式建立的流物件具有一個長度為numBytes的回推緩衝區,從而允許將多個位元組回 推到輸入流中。 除了來自InputStream的方法,PushbackInputStream類還提供了unread()方法,如下所示: void unread(int b) void unread(byte[] buffer) void unread(byte buffer,int offset,int numBytes) 第一種形式回推b的低位元組,這會是後續的read()呼叫返回的下一個位元組。 第二種形式回推buffer中的位元組。 第三種形式回推buffer中從offset開始的numBytes個位元組。 當回推緩衝區已滿時,如果試圖回推位元組,就會丟擲IOException異常。
警告: PushbackInputStream物件會使得InputStream物件(用於建立PushbackInputStream 物件)的 mark()或reset()方法無效。對於準備使用mark()或reset()方法的任何流來說,都應當使用 markSupported()方法進行檢查。
7.9 SequenceInputStream類 SequenceInputStream類允許連結多個InputStream物件。SequenceInputStream物件的構造與 其他所有InputStream對像都不同。SequenceInputStream建構函式使用一對InputStream物件 或InputStream物件的一個Enumeration物件作為引數: SequenceInputStream(InputStream first, InputStream second) SequenceInputStream(Enumeration<? extends InputStream> streamEnum) 在操作上,該類從第一個InputStream物件進行讀取,直到讀取完全部內容,然後切換到第二 個InputStream物件。對於使用Enumeration物件的情況,該類將持續讀取所有InputStream 物件中的內容,直到到達最後一個InputStream物件的末尾為止。 當到達每個檔案的末尾時,與之關聯的流就會被關閉。 關閉通過SequenceInputStream建立的流,會導致關閉所有未關閉的流。
7.10 PrintStream類 PrintStream類提供了我們曾使用過的來自System檔案控制代碼System.out的所有輸出功能,這使得 PrintStream成為Java中最常用的類之一。 PrintStream類實現了Appendable、AutoCloseable、Closeable以及Flushable介面。 PrintStream類的建構函式: PrintStream(OutputStream outputStream) PrintStream(OutputStream outputStream,boolean autoFlushingOn) PrintStream(OutputStream outputStream,boolean autoFlushingOn,String charSet)
throws UnsupportedEndingException 在此,outputStream指定了用於接收輸出的開啟的OutputStream物件。autoFlushingOn引數 控制每次寫入一個換行符(\n)或位元組陣列,抑或呼叫println()方法時,是否自動重新整理輸出 緩衝區。如果autoFlushingOn為true,就自動重新整理;如果為false,就不自動重新整理。 第一個建構函式不自動重新整理緩衝區。可以通過charSet傳遞的名稱來指定字元編碼。
下面幾個建構函式提供了構造能夠將輸出寫入檔案中的PrintStream物件的簡單方式: PrintStream(File outputFile) throws FileNotFoundExeption PrintStream(File outputFile,String charSet)
throws FileNotFoundException,UnsupportedEncodingException PrintStream(String outputFileName) throws FileNotFoundException PrintStream(String outputFileName,String charSet) throws FileNotFoundException, UnsupportedEncodingException 這些建構函式從File物件或根據指定的檔名建立PrintStream物件。兩種情況中,都會自動 建立檔案。所有之前存在的同名檔案都會被銷燬。一旦建立PrintStream物件,就可以將所有 輸出定向到指定的檔案中。可以通過charSet傳遞的名稱來指定字元編碼。
注意:如果存在安全管理器,那麼當發生安全性違規時,有些PrintStream建構函式會丟擲 SecurityException異常。
PrintStream為所有型別(包括Object)都支援print()和println()方法。如果引數不是基本 型別,那麼PrintStream方法會呼叫物件的toString()方法並顯示結果。 從jdk5開始,Java為PrintStream類添加了printf()方法。該方法允許指定將要寫入的資料的 精確格式。 printf()方法具有以下一般形式: PrintStream printf(String fmtString,Object ... args) PrintStream printf(Locale loc,String fmtString,Object ... args)
PrintStream類還定義了format()方法: PrintStream format(String fmtString,Object ... args) PrintStream format(Locale loc,String fmtString,Object ...args)
7.11 DataOutputStream類和DataInputStream類 通過DataOutputStream和DataInputStream類,可以向流中寫入基本型別資料或從流中讀取基本 型別資料。他們分別實現了DataOutput和DataInput介面,這些介面定義了將基本型別值轉換 成位元組序列或將位元組序列轉換成基本型別值的方法。
7.12 RandomAccessFile類 該類封裝了隨機訪問檔案的功能。 seek()方法用於設定檔案指標在檔案中的當前位置 void seek(long newPos) throws IOException
setLength()方法。

8 字元流
8.1 Reader類 Reader是抽象類,定義了Java的流字元輸入模型。該類實現了AutoCloseable、Closeable以及 Readable介面。
8.2 Writer類 Writer是抽象類,定義了Java的流字元的輸出模型,實現了AutoCloseable、Closeable、Flushable 以及Appendable介面。
8.3 FileReader類 FileReader類可以建立用於讀取檔案內容的Reader物件,建構函式: FileReader(String filePath) FileReader(File fileObj) 其中,filePath是檔案的完整路徑名,fileObj是描述檔案的File物件。
8.4 FileWriter類 該類可以建立能夠用於寫入檔案的Writer物件。
其他字元流與對應的位元組流類似
9 Console類 JDK6將Console類新增到java.io包中,該類用於從控制檯讀取內容以及向控制檯寫入內容, 並且實現了Flushable介面。 Console類沒有提供建構函式。相反,該類通過呼叫System.console()方法獲取Console物件, 如下所示: static Console.console() 如果控制檯可用,就返回對控制檯的引用;否則返回null。
10 序列化
10.1 Serializable介面 只有實現了Serializable介面的類才能夠通過序列化功能進行儲存和恢復。 Serizlizable介面沒有定義成員,只是簡單地用於指示類可以被序列化。如果一個類是可序列化的, 那麼這個類的所有子類也收拾可序列化的。 宣告為transient的變數不能通過序列化功能進行儲存。 此外,也不能儲存static變數。
10.2 Externalizable介面
10.3 ObjectOutput介面
10.4 ObjectOutputStream類
10.5 ObjectInput介面
10.6 ObjectInputStream類