系統學習 Java IO (三)----FileInputStream/FileOutputStream & RandomAccessFile
目錄:ofollow,noindex" target="_blank">系統學習 Java IO---- 目錄,概覽
FileInputStream
這是一個簡單的FileInputStream示例:
InputStream input = new FileInputStream("D:\\input.txt"); int data = input.read(); while(data != -1) { //do something with data... doSomethingWithData(data); data = input.read(); } input.close();
注意:為了程式碼清晰,這裡並沒有考慮處理異常的情況,IO 異常處理有專門的介紹。
FileInputStream 構造器
FileInputStream 類有三個不同的建構函式,可用於建立 FileInputStream 例項。
- 建構函式將一個包含檔案系統中要讀取的檔案所在的路徑 String 作為引數:
String path = "D:\\.txt"; FileInputStream fileInputStream = new FileInputStream(path);
注意路徑需要雙反斜槓\\
,因為反斜槓是Java字串中的轉義字元。 要獲得單個反斜槓,需要使用轉義序列\。
在unix上,檔案路徑可能如下所示:
String path = "/home/czwbig/data/thefile.txt";
注意使用正斜槓/
作為目錄分隔符。 這是在 unix 上編寫檔案路徑的方法。 實際上,Java 也會理解在 Windows 上使用/
作為目錄分隔符,例如new FileInputStream("D:/out.txt")
- 建構函式將 File 物件作為引數。 File 物件必須指向要讀取的檔案。 這是一個例子:
String path = "D:\\out.txt"; Filefile = new File(path); FileInputStream fileInputStream = new FileInputStream(file);
應該使用哪個建構函式取決於在開啟 FileInputStream 之前具有該路徑的形式。 如果您已經有一個 String 或 File ,只需按原樣使用它。 將 String 轉換為 File 或將 File 轉換為 String 沒有特別的好處。
-
public FileInputStream(FileDescriptor fdObj)
通過使用檔案描述符 fdObj 建立一個 FileInputStream,該檔案描述符表示到檔案系統中某個實際檔案的現有連線。不常用。
read(byte[])
作為 InputStream 的子類,FileInputStream 還有兩個read()方法,可以將資料讀入位元組陣列。 可以在我的有關 InputStream 的文章中閱讀,不展開了。
close() 統一在 Java IO 異常處理講解了
FileOutputStream
這是一個簡單的FileOutputStream示例:
OutputStream output = new FileOutputStream("D:\\out.txt"); while(moreData) { int data = getMoreData(); output.write(data); } output.close();
FileOutputStream 構造器
和 FileInputStream 的3個構造器差不多,參考上面即可。
另外多了兩個構造方法:
- FileOutputStream(File file, boolean append) ;
-
FileOutputStream(String name, boolean append) ;
引數 append - 如果為 true,則將位元組寫入檔案末尾處,而不是寫入檔案開始處,這樣就能不覆蓋檔案,而是追加內容。
write(...); flush()
參考 OutputStream 。
RandomAccessFile
這裡的隨機訪問是指,隨便指定一個位置,訪問它;而不是隨便訪問一個位置。
在使用RandomAccessFile類之前,必須例項化它。它有兩個構造器,如下:
- RandomAccessFile(File file, String mode)
-
RandomAccessFile(String name, String mode)
例項:
RandomAccessFile file = new RandomAccessFile("c:\\data\\file.txt", "rw");
引數:
file、name- 該檔案物件
mode - 訪問模式,如下表:
值 | 含意 |
---|---|
"r" | 以只讀方式開啟。呼叫結果物件的任何 write 方法都將導致丟擲 IOException。 |
"rw" | 開啟以便讀取和寫入。如果該檔案尚不存在,則嘗試建立該檔案。 |
"rws" | "rw" + “sync”,另外還要求對檔案的內容或元資料的每個更新都同步寫入到底層儲存裝置。 |
"rwd" | "rw" + “data”,另外還要求對檔案內容的每個更新都同步寫入到底層儲存裝置。 |
"rwd" 模式
可用於減少執行的 I/O 運算元量.使用 "rwd" 僅要求更新要寫入儲存的檔案的內容;使用 "rws" 要求更新要寫入的檔案內容及其元資料,這通常要求至少一個以上的低級別 I/O 操作。
"rws" 和 "rwd" 模式
如果該檔案位於本地儲存裝置上,那麼當返回此類的一個方法的呼叫時,可以保證由該呼叫對此檔案所做的所有更改均被寫入該裝置。這對確保在系統崩潰時不會丟失重要資訊特別有用。如果該檔案不在本地裝置上,則無法提供這樣的保證。
使用 RandomAccessFile 在檔案中跳轉
要在 RandomAccessFile 中的特定位置讀取或寫入,必須首先將檔案指標放在要讀取或寫入的位置。 這是使用 seek() 方法完成的。 可以通過呼叫 getFilePointer() 方法獲取檔案指標的當前位置。
read() 方法將檔案指標遞增為指向剛剛讀取的位元組後文件中的下一個位元組! 這意味著您可以繼續呼叫 read() 而無需手動移動檔案指標。
看如下例子:
public class RandomAccessFileExample { public static void main(String[] args) throws IOException { // out.txt 此時的檔案內容為 "123456789" RandomAccessFile file = new RandomAccessFile("D:\\out.txt", "rw"); System.out.println("pointer: " + file.getFilePointer()); // 輸出 pointer: 0 System.out.println("char: " + (char) file.read()); // 輸出 char: 1 System.out.println("pointer: " + file.getFilePointer()); // 輸出 pointer: 1 file.seek(4); // 下標從 0 開始的,讓其指向第 5 個位元組 System.out.println("pointer: " + file.getFilePointer()); // 輸出 pointer: 4 System.out.println("char: " + (char) file.read()); // 輸出 char: 5 System.out.println("pointer: " + file.getFilePointer()); // 輸出 pointer: 5 file.close(); } }
read & write
從 RandomAccessFile 讀取是使用其眾多 read() 方法之一完成的。
方法 | 描述 |
---|---|
read(byte[] b) | 將最多 b.length 個數據位元組從此檔案讀入 byte 陣列。 |
readByte() | 從此檔案讀取一個有符號的八位值。 |
readChar() | 從此檔案讀取一個字元。 |
readFully(byte[] b) | 將 b.length 個位元組從此檔案讀入 byte 陣列,並從當前檔案指標開始。 |
readLine() | 從此檔案讀取文字的下一行。 |
skipBytes(int n) | 嘗試跳過輸入的 n 個位元組以丟棄跳過的位元組。 |
setLength(long newLength) | 設定此檔案的長度。 |
writeChars(String s) | 按字元序列將一個字串寫入該檔案。 |