- Java核心技術·卷Ⅱ:高級特性(原書第10版)
- (美)凱S.霍斯特曼
- 1671字
- 2020-10-30 18:10:38
2.1.3 組合輸入/輸出流過濾器
FileInputStream和FileOutputStream可以提供附著在一個磁盤文件上的輸入流和輸出流,而你只需向其構造器提供文件名或文件的完整路徑名。例如:

這行代碼可以查看在用戶目錄下名為“employee.dat”的文件。
提示:所有在java.io中的類都將相對路徑名解釋為以用戶工作目錄開始,你可以通過調用System.getProperty("user.dir")來獲得這個信息。
警告:由于反斜杠字符在Java字符串中是轉義字符,因此要確保在Windows風格的路徑名中使用\\(例如,C:\\Windows\\win.ini)。在Windows中,還可以使用單斜杠字符(C:/Windows/win.ini),因為大部分Windows文件處理的系統調用都會將斜杠解釋成文件分隔符。但是,并不推薦這樣做,因為Windows系統函數的行為會因與時俱進而發生變化。因此,對于可移植的程序來說,應該使用程序所運行平臺的文件分隔符,我們可以通過常量字符串java.io.File.separator獲得它。
與抽象類InputStream和OutputStream一樣,這些類只支持在字節級別上的讀寫。也就是說,我們只能從fin對象中讀入字節和字節數組。

正如下節中看到的,如果我們只有DataInputStream,那么我們就只能讀入數值類型:

但是正如FileInput Stream沒有任何讀入數值類型的方法一樣,DataInputStream也沒有任何從文件中獲取數據的方法。
Java使用了一種靈巧的機制來分離這兩種職責。某些輸入流(例如FileInputStream和由URL類的openStream方法返回的輸入流)可以從文件和其他更外部的位置上獲取字節,而其他的輸入流(例如DataInputStream)可以將字節組裝到更有用的數據類型中。Java程序員必須對二者進行組合。例如,為了從文件中讀入數字,首先需要創建一個FileInputStream,然后將其傳遞給DataInputStream的構造器:

如果再次查看圖2-1,你就會看到FilterInputStream和FilterOutputStream類。這些文件的子類用于向處理字節的輸入/輸出流添加額外的功能。
你可以通過嵌套過濾器來添加多重功能。例如,輸入流在默認情況下是不被緩沖區緩存的,也就是說,每個對read的調用都會請求操作系統再分發一個字節。相比之下,請求一個數據塊并將其置于緩沖區中會顯得更加高效。如果我們想使用緩沖機制,以及用于文件的數據輸入方法,那么就需要使用下面這種相當恐怖的構造器序列:

注意,我們把DataInputStream置于構造器鏈的最后,這是因為我們希望使用DataInputStream的方法,并且希望它們能夠使用帶緩沖機制的read方法。
有時當多個輸入流鏈接在一起時,你需要跟蹤各個中介輸入流(intermediate input stream)。例如,當讀入輸入時,你經常需要預覽下一個字節,以了解它是否是你想要的值。Java提供了用于此目的的PushbackInputStream:

現在你可以預讀下一個字節:

并且在它并非你所期望的值時將其推回流中。

但是讀入和推回是可應用于可回推(pushback)輸入流的僅有的方法。如果你希望能夠預先瀏覽并且還可以讀入數字,那么你就需要一個既是可回推輸入流,又是一個數據輸入流的引用。

當然,在其他編程語言的輸入/輸出流類庫中,諸如緩沖機制和預覽等細節都是自動處理的。因此,相比較而言,Java就有一點麻煩,它必須將多個流過濾器組合起來。但是,這種混合并匹配過濾器類以構建真正有用的輸入/輸出流序列的能力,將帶來極大的靈活性,例如,你可以從一個ZIP壓縮文件中通過使用下面的輸入流序列來讀入數字(請參見圖2-4):

(請查看2.3.3節以了解更多有關Java處理ZIP文件功能的知識。)

圖2-4 過濾器流序列
java.io.FileInputStream 1.0
·FileInputStream(String name)
·FileInputStream(File file)
使用由name字符串或file對象指定路徑名的文件創建一個新的文件輸入流(File類在本章結尾處描述)。非絕對的路徑名將按照相對于VM啟動時所設置的工作目錄來解析。
java.io.FileOutputStream 1.0
·FileOutputStream(String name)
·FileOutputStream(String name,boolean append)
·FileOutputStream(File file)
·FileOutputStream(File file,boolean append)
使用由name字符串或file對象指定路徑名的文件創建一個新的文件輸出流(File類在本章結尾處描述)。如果append參數為true,那么數據將被添加到文件尾,而具有相同名字的已有文件不會被刪除;否則,這個方法會刪除所有具有相同名字的已有文件。
java.io.BufferedInputStream 1.0
·BufferedInputStream(InputStream in)
創建一個帶緩沖區的輸入流。帶緩沖區的輸入流在從流中讀入字符時,不會每次都對設備訪問。當緩沖區為空時,會向緩沖區中讀入一個新的數據塊。
java.io.BufferedOutputStream 1.0
·BufferedOutputStream(OutputStream out)
創建一個帶緩沖區的輸出流。帶緩沖區的輸出流在收集要寫出的字符時,不會每次都對設備訪問。當緩沖區填滿或當流被沖刷時,數據就被寫出。
java.io.PushbackInputStream 1.0
·PushbackInputStream(InputStream in)
·PushbackInputStream(InputStream in,int size)
構建一個可以預覽一個字節或者具有指定尺寸的回推緩沖區的輸入流。
·void unread(int b)
回推一個字節,它可以在下次調用read時被再次獲取。
參數:b 要再次讀入的字節。
- Vue.js設計與實現
- FuelPHP Application Development Blueprints
- Vue.js 3.0源碼解析(微課視頻版)
- Rust Cookbook
- C語言程序設計實踐教程
- Getting Started with Python Data Analysis
- Java程序設計
- C語言程序設計實驗指導 (第2版)
- 現代C++編程實戰:132個核心技巧示例(原書第2版)
- Learning VMware vSphere
- 從零開始學Selenium自動化測試:基于Python:視頻教學版
- 程序員的成長課
- Visual C++開發寶典
- 網絡綜合布線與組網實戰指南
- PHP 7 Programming Blueprints