系統(tǒng)學(xué)習(xí) Java IO (四)----文件的讀寫和隨機(jī)訪問(wèn) FileInputStream/FileOutputStream & RandomAccessFile

目錄:系統(tǒng)學(xué)習(xí) Java IO---- 目錄,概覽

文件輸入流 FileInputStream

這是一個(gè)簡(jiǎn)單的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();

注意:為了代碼清晰,這里并沒(méi)有考慮處理異常的情況,IO 異常處理有專門的介紹。

FileInputStream 構(gòu)造器

FileInputStream 類有三個(gè)不同的構(gòu)造函數(shù),可用于創(chuàng)建 FileInputStream 實(shí)例。

  • 構(gòu)造函數(shù)將一個(gè)包含文件系統(tǒng)中要讀取的文件所在的路徑 String 作為參數(shù): FileInputStream fileInputStream = new FileInputStream( "D:\\1.txt");
    注意路徑需要雙反斜杠\\,因?yàn)榉葱备苁荍ava字符串中的轉(zhuǎn)義字符,通過(guò)此方式獲得單個(gè)反斜杠。
    在unix上,文件路徑可能如下所示:
    String path = "/home/czwbig/data/thefile.txt";
    注意使用正斜杠/作為目錄分隔符。 這是在 unix 上編寫文件路徑的方法。 實(shí)際上,Java 也會(huì)理解在 Windows 上使用/作為目錄分隔符,例如new FileInputStream("D:/out.txt")

  • 構(gòu)造函數(shù)將 File 對(duì)象作為參數(shù)。 File 對(duì)象必須指向要讀取的文件。 這是一個(gè)例子:

String path = "D:\\out.txt";
File   file = new File(path);
FileInputStream fileInputStream = new FileInputStream(file);

應(yīng)該使用哪個(gè)構(gòu)造函數(shù)取決于在打開 FileInputStream 之前具有該路徑的形式。 如果您已經(jīng)有一個(gè) String 或 File ,只需按原樣使用它。 將 String 轉(zhuǎn)換為 File 或?qū)?File 轉(zhuǎn)換為 String 沒(méi)有特別的好處。

  • public FileInputStream(FileDescriptor fdObj)
    通過(guò)使用文件描述符 fdObj 創(chuàng)建一個(gè) FileInputStream,該文件描述符表示到文件系統(tǒng)中某個(gè)實(shí)際文件的現(xiàn)有連接。不常用。
read(byte[])

作為 InputStream 的子類,F(xiàn)ileInputStream 還有兩個(gè) read() 方法,可以將數(shù)據(jù)讀入字節(jié)數(shù)組。 可以在我的有關(guān) InputStream 的文章中閱讀,不展開了。

close()

建議使用 try 自動(dòng)關(guān)閉,參考 IO 異常處理章節(jié)。


文件輸出流 FileOutputStream

這是一個(gè)簡(jiǎn)單的 FileOutputStream 示例:

OutputStream output = new FileOutputStream("D:\\out.txt");
while(moreData) {
  int data = getMoreData();
  output.write(data);
}
output.close();
FileOutputStream 構(gòu)造器

和 FileInputStream 的 3 個(gè)構(gòu)造器差不多,參考上面即可。
另外多了兩個(gè)構(gòu)造方法:

  • FileOutputStream(File file, boolean append) ;
  • FileOutputStream(String name, boolean append) ;
    參數(shù) append :如果不給出 append 參數(shù),其值默認(rèn)是 false 的,即默認(rèn)是覆蓋模式。如果為 true,則將字節(jié)寫入文件末尾處,而不是寫入文件開始處,這樣就能不覆蓋文件,而是追加內(nèi)容。
    所以,在新建 FileOutputStream 對(duì)象的時(shí)候,要非常小心,只要沒(méi)有指定 append 為 true ,那么只要 FileOutputStream 對(duì)象創(chuàng)建成功,對(duì)應(yīng)的文件會(huì)被立即清空。
    如代碼:OutputStream outputStream = new FileOutputStream("D:\\test\\1.txt"); ,執(zhí)行后對(duì)應(yīng)的 1.txt 文件(如果存在)會(huì)立刻被清空,而不管有沒(méi)有調(diào)用 OutputStream 的 write() 方法。
write(...) and flush()

參考 OutputStream 。

使用 RandomAccessFile 隨機(jī)訪問(wèn)文件

這里的隨機(jī)訪問(wèn)是指,指定任何一個(gè)位置,都能夠訪問(wèn)它;而不是不確定的隨機(jī)訪問(wèn)某一個(gè)位置。
在使用 RandomAccessFile 類之前,必須實(shí)例化它。它有兩個(gè)構(gòu)造器,如下:

  1. RandomAccessFile(File file, String mode)
  2. RandomAccessFile(String name, String mode)

實(shí)例:

RandomAccessFile file = new RandomAccessFile("c:\\data\\file.txt", "rw");

參數(shù):
file、name- 該文件對(duì)象
mode - 訪問(wèn)模式,如下表:

含意
"r" 以只讀方式打開。調(diào)用結(jié)果對(duì)象的任何 write 方法都將導(dǎo)致拋出 IOException。
"rw" 打開以便讀取和寫入。如果該文件尚不存在,則嘗試創(chuàng)建該文件。
"rws" "rw" + “sync”,另外還要求對(duì)文件的內(nèi)容或元數(shù)據(jù)的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備。
"rwd" "rw" + “data”,另外還要求對(duì)文件內(nèi)容的每個(gè)更新都同步寫入到底層存儲(chǔ)設(shè)備。
"rwd" 模式

可用于減少執(zhí)行的 I/O 操作數(shù)量.使用 "rwd" 僅要求更新要寫入存儲(chǔ)的文件的內(nèi)容;使用 "rws" 要求更新要寫入的文件內(nèi)容及其元數(shù)據(jù),這通常要求至少一個(gè)以上的低級(jí)別 I/O 操作。

"rws" 和 "rwd" 模式

如果該文件位于本地存儲(chǔ)設(shè)備上,那么當(dāng)返回此類的一個(gè)方法的調(diào)用時(shí),可以保證由該調(diào)用對(duì)此文件所做的所有更改均被寫入該設(shè)備。這對(duì)確保在系統(tǒng)崩潰時(shí)不會(huì)丟失重要信息特別有用。如果該文件不在本地設(shè)備上,則無(wú)法提供這樣的保證。

在文件中跳轉(zhuǎn)

要在 RandomAccessFile 中的特定位置讀取或?qū)懭?,必須首先將文件指針?lè)旁谝x取或?qū)懭氲奈恢谩?這是使用 seek() 方法完成的。 可以通過(guò)調(diào)用 getFilePointer() 方法獲取文件指針的當(dāng)前位置。
read() 方法將文件指針遞增為指向剛剛讀取的字節(jié)后文件中的下一個(gè)字節(jié)! 這意味著可以繼續(xù)調(diào)用 read() 而無(wú)需手動(dòng)移動(dòng)文件指針。
看如下例子:

public class RandomAccessFileExample {
    public static void main(String[] args) throws IOException {
        // out.txt 此時(shí)的文件內(nèi)容為 "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); // 下標(biāo)從 0 開始的,讓其指向第 5 個(gè)字節(jié)

        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 個(gè)數(shù)據(jù)字節(jié)從此文件讀入 byte 數(shù)組。
readByte() 從此文件讀取一個(gè)有符號(hào)的八位值。
readChar() 從此文件讀取一個(gè)字符。
readFully(byte[] b) 將 b.length 個(gè)字節(jié)從此文件讀入 byte 數(shù)組,并從當(dāng)前文件指針開始。
readLine() 從此文件讀取文本的下一行。
skipBytes(int n) 嘗試跳過(guò)輸入的 n 個(gè)字節(jié)以丟棄跳過(guò)的字節(jié)。
setLength(long newLength) 設(shè)置此文件的長(zhǎng)度。
writeChars(String s) 按字符序列將一個(gè)字符串寫入該文件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 java.io 包幾乎包含了所有操作輸入、輸出需要的類。所有這些流類代表了輸入源和輸出目標(biāo)。java.io ...
    Steven1997閱讀 9,416評(píng)論 1 25
  • 五、IO流 1、IO流概述 (1)用來(lái)處理設(shè)備(硬盤,控制臺(tái),內(nèi)存)間的數(shù)據(jù)。(2)java中對(duì)數(shù)據(jù)的操作都是通過(guò)...
    佘大將軍閱讀 585評(píng)論 0 0
  • 1、IO流 1.1、概述 之前學(xué)習(xí)的File類它只能操作文件或文件夾,并不能去操作文件中的數(shù)據(jù)。真正保存數(shù)據(jù)的是文...
    Villain丶Cc閱讀 2,785評(píng)論 0 5
  • 對(duì)于我這種不喜歡在人前說(shuō)話的來(lái)說(shuō),在虛擬的世界里也許說(shuō)得會(huì)多一點(diǎn),但是同學(xué)群我總是很少發(fā)言,其實(shí)也不是怕說(shuō)錯(cuò)什么,...
    逸媽媽閱讀 407評(píng)論 0 0
  • 今天這篇文章將是我之前挖下的坑被填平的一天,在9月14號(hào)的時(shí)候,我曾經(jīng)寫下一篇文章“寫的文章沒(méi)人看,還要不要寫?”...
    島嶼書閱讀 795評(píng)論 12 7

友情鏈接更多精彩內(nèi)容