Java RandomAccessFile類:動態讀取檔案內容

2020-07-16 10:05:17
所謂動態讀取是指從檔案的任意位置開始存取檔案,而不是必須從檔案開始位置讀取到檔案末尾。動態讀取需要用到 Java 中的 RandomAccessFile 類。

RandomAccessFile 是 Java 輸入/輸出流體系中功能最豐富的檔案內容存取類,它提供了眾多的方法來存取檔案內容,它既可以讀取檔案內容,也可以向檔案輸出資料。由於 RandomAccessFile 可以從任意位置存取檔案,所以在只需要存取檔案部分內容的情況下,使用 RandonAccessFile 類是一個很好的選擇。

RandomAccessFile 物件包含了一個記錄指標,用以標識當前讀寫處的位置,當程式新建立一個 RandomAccessFile 物件時,該物件的檔案記錄指標位於檔案頭(也就是 0 處),當讀/寫了 n 個位元組後,檔案記錄指標將會向後移動 n 個位元組。除此之外,RandonAccessFile 可以自由移動該記錄指標,既可以向前移動,也可以向後移動。

RandomAccessFile 類中提供了一些常用讀取和寫入資料的方法,如表 1 所示。

表 1 RandomAccessFile 類的常用方法
方法名及返回值型別 說明
boolean readBoolean() 從檔案中讀取一個 boolean 值
byte readByte() 從檔案中讀取一個帶符號位的位元組
char readChar() 從檔案中讀取一個字元
int readlnt() 從檔案中讀取一個帶符號位的整數
long readLong() 從檔案中讀取一個帶符號位的 long 值
String readLine() 從檔案中讀取下一行文字
void seek(long pos) 指定從檔案起始位置開始的指標偏移量
void writeBoolean(boolean v) 以位元組的形式向檔案中寫入一個 boolean 值
void writeByte(int v) 以單位元組的形式向檔案中寫入一個 byte 值
void writeChar(int v) 以雙位元組的形式向檔案中寫入一個 char 值
void writelnt(int v) 以4位元組的形式向檔案中寫入一個整數
writeLong(long v) 以8位元組的形式向檔案中寫入一個 long 值
void writeBytes(String s) 以位元組序列的形式向檔案中寫入一個字串
void skipBytes(int n) 以當前檔案指標位置為起始點,跳過 n 位元組

RandomAccessFile 類的構造方法有如下兩種過載形式。
  1. RandomAccessFile(File file, String mode):存取引數 file 指定的檔案,存取形式由引數 mode 指定,mode 引數有兩個常用的可選值 r 和 rw,其中 r 表示唯讀,rw 表示讀寫。
  2. RandomAccessFile(String name, String mode):存取引數 name 指定的檔案,mode 引數的含義同上。

注意:如果使用 rw 方式宣告 RandomAccessFile 物件時,要寫入的檔案不存在,系統將自動進行建立。

例 1

編寫一個程式,使用 RandomAccessFileDemo 類建立一個 words.txt 檔案,然後寫入一個長中文字串,再從第 6 個位元組開始讀取並輸出。

1)建立一個 RandomAccessFileDemo 類物件。在 main() 方法中建立到 D:JavaCodeswords.txt 的 File 物件,如果該檔案已經存在則先刪除再建立,程式碼如下所示。
public class RandomAccessFileDemo {
    public static void main(String[] args) {
        try {
            File file = new File("D:myJavawords.txt"); // 指定檔案路徑
            if (file.exists()) { // 判斷檔案是否存在
                file.delete();
                file.createNewFile();
            }
        } catch (IOException e) {
            System.out.print(e);
        }
    }
}
2)建立 RandomAccessFile 物件,以讀寫方式操作 File 物件。定義一個要寫入的字串,再將其進行格式的轉換。這樣是為了使其寫入檔案的內容不出現亂碼,再將轉換後的內容寫入檔案,程式碼如下所示。
RandomAccessFile raf = new RandomAccessFile(file,"rw");
String str1 = "晴天,陰天,多雲,小雨,大風,中雨,小雪,雷陣雨";    // 要寫入的字串
String str2 = new String(str1.getBytes("GBK"),"ISO-8859-1");    // 編碼轉換
raf.writeBytes(str2);    //寫入檔案
3)列印出當前指標的位置,然後將其移動到第 6 個位元組。再定義一個長度為 2 的 byte 陣列,然後開始進行內容的迴圈讀取,將讀出的內容以字串的形式輸出到控制台,程式碼如下所示。
System.out.println("當前檔案指標的位置:" + raf.getFilePointer());
raf.seek(6); // 移動檔案指標
System.out.println("從檔案頭跳過6個位元組,現在檔案內容如下:");
byte[] buffer = new byte[2];
int len = 0;
while ((len = raf.read(buffer, 0, 2)) != -1) {
    System.out.print(new String(buffer, 0, len)); // 輸出檔案內容
}
4)執行程式,程式執行結果如下所示,顯示了寫入字串後指標的位置,以及從檔案開關跳過 6 個位元組後讀取到的字串,圖 1 為寫入檔案中的字串內容。
當前檔案指標的位置:48
從檔案頭跳過6個位元組,現在檔案內容如下:
陰天,多雲,小雨,大風,中雨,小雪,雷陣雨

word.txt 文件內容
圖 1  word.txt 檔案內容