[Java]RandomAccessFile類詳解

sjf0115發表於2015-12-24

RandomAccessFile適用於大小已知的記錄組成的檔案,提供的對檔案訪問,既可以讀檔案,也可以寫檔案,並且支援隨機訪問檔案,可以訪問檔案的任意位置。檔案中記錄的大小不一定都相同,只要我們知道記錄的大小和位置。但是該類僅限於操作檔案。

RandomAccessFile不屬於InputStream和OutputStream繼承層次結構中的一部分。除了實現DataInput和DataOutput介面之外(DataInputStream和DataOutputStream也實現了這兩個介面),它和這兩個繼承層次結構沒有任何關係,它甚至不使用InputStream和OutputStream類中已經存在的任何功能;它是一個完全獨立的類,從頭開始編寫其所有的方法(大多數都是本地的)。這麼做是因為RandomAccessFile擁有和別的IO型別本質上不同的行為,因為我們可以在一個檔案內向前和向後移動。它是一個直接繼承Object的,獨立的類。

本質上說,RandomAccessFile的工作方式類似於把DataInputStream和DataOutputStream結合起來,還新增了一些方法,其中方法getFilePointer( )用來查詢當前所處的檔案位置,seek( )用來在檔案內移至新的位置,length( )用來判斷檔案大小。此外,它的構造方法還需要一個引數來表示開啟模式(只讀方式 r 讀寫方式 rw),它不支援只寫檔案。

只有RandomAccessFile支援搜尋方法(seek()),並且這個方法也只適用於檔案。BufferedInputStream卻只能允許標註(mark())位置(其值儲存在內部某個變數內)和重新設定位置(reset()),但是這些功能有限,不是非常實用。

在JDK 1.4中,RandomAccessFile的絕大多數功能(但不是全部)已經被nio記憶體對映檔案給取代了。

方法:

方法 描述 void close() 關閉此隨機訪問檔案流並釋放與該流關聯的所有系統資源。 FileChannel getChannel () 返回與此檔案關聯的唯一 FileChannel 物件。 FileDescriptor getFD () 返回與此流關聯的不透明檔案描述符物件。 long getFilePointer () 返回此檔案中的當前偏移量,用來查詢當前所處的位置。 long length() 返回此檔案的長度。 int read() 從此檔案中讀取一個資料位元組 int read(byte[] b) 將最多 b.length 個資料位元組從此檔案讀入 byte 陣列。 int read(byte[] b,int off,int len) 將最多 len 個資料位元組從此檔案讀入 byte 陣列。 boolean readBoolean() 從此檔案讀取一個 boolean。 byte readByte() 從此檔案讀取一個有符號的八位值。 char readChar() 從此檔案讀取一個字元 double readDouble() 從此檔案讀取一個 double。 float readFloat() 從此檔案讀取一個 float。 void readFully(byte[] b) 將 b.length 個位元組從此檔案讀入 byte 陣列,並從當前檔案指標開始。 void readFully(byte[] b,int off,int len) 將正好 len 個位元組從此檔案讀入 byte 陣列,並從當前檔案指標開始。 int readInt() 從此檔案讀取一個有符號的 32 位整數。 String readLine() 從此檔案讀取文字的下一行。 long readLong() 從此檔案讀取一個有符號的 64 位整數。 short readShort() 從此檔案讀取一個有符號的 16 位數。 int readUnsignedByte() 從此檔案讀取一個無符號的八位數 int readUnsignedShort() 從此檔案讀取一個無符號的 16 位數。 String readUTF() 從此檔案讀取一個字串。 void seek(long pos) 設定到此檔案開頭測量到的檔案指標偏移量,在該位置發生下一個讀取或寫入操作。 void setLength(long newLength) 設定此檔案的長度。 int skipBytes(int n) 嘗試跳過輸入的 n 個位元組以丟棄跳過的位元組。 void write(byte[] b) 將 b.length 個位元組從指定 byte 陣列寫入到此檔案,並從當前檔案指標開始。 void write(byte[] b, int off, int len) 將 len 個位元組從指定 byte 陣列寫入到此檔案,並從偏移量 off 處開始。 void write(int b) 向此檔案寫入指定的位元組。 void writeBoolean(boolean v) 按單位元組值將 boolean 寫入該檔案。 void writeByte(int v) 按單位元組值將 byte 寫入該檔案 void writeBytes(String s) 按位元組序列將該字串寫入該檔案。 void writeChar(int v) 按雙位元組值將 char 寫入該檔案,先寫高位元組。 void writeChars(String s) 按字元序列將一個字串寫入該檔案。 void writeDouble(double v) 使用 Double 類中的 doubleToLongBits 方法將雙精度引數轉換為一個 long,然後按八位元組數量將該 long 值寫入該檔案,先定高位元組。 void writeFloat(float v) 使用 Float 類中的 floatToIntBits 方法將浮點引數轉換為一個 int,然後按四位元組數量將該 int 值寫入該檔案,先寫高位元組。 void writeInt(int v) 按四個位元組將 int 寫入該檔案,先寫高位元組。 void writeLong(long v) 按八個位元組將 long 寫入該檔案,先寫高位元組 void writeShort(int v) 按兩個位元組將 short 寫入該檔案,先寫高位元組。 void writeUTF(String str) 使用 modified UTF-8 編碼以與機器無關的方式將一個字串寫入該檔案。

案例:

package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.Arrays;
public class FileDemo {

    public static void main(String[] args) {
        String pathname = "D:\\Recommended system.txt";
        // 建立檔案例項
        File file = new File(pathname);

        try {
            // 判斷檔案是否存在
            if(!file.exists()){
                file.createNewFile();
            }//if

            // 讀寫方式開啟檔案
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
            System.out.println("當前所處的位置:"+randomAccessFile.getFilePointer());

            // write 從當前指標開始寫入,寫入一個位元組
            randomAccessFile.write('A');
            System.out.println("當前所處的位置:"+randomAccessFile.getFilePointer());

            randomAccessFile.write('B');

            int num = 0x7fffffff;
            // 如果用write方法,每次只能寫一個位元組,需要寫4次
            randomAccessFile.write(num >>> 24);
            randomAccessFile.write(num >>> 16);
            randomAccessFile.write(num >>> 8);
            randomAccessFile.write(num);
            System.out.println("當前所處的位置:"+randomAccessFile.getFilePointer());

            // 或者是用writeInt方法 一次寫入
            randomAccessFile.writeInt(num);
            System.out.println("當前所處的位置:"+randomAccessFile.getFilePointer());

            // 檔案指標指向檔案開頭
            randomAccessFile.seek(0);
            // 一次性讀取 把檔案中內容都讀到位元組陣列中
            byte[] buffer = new byte[(int)randomAccessFile.length()];
            randomAccessFile.read(buffer);

            for (byte b : buffer) {
                // 16進位制輸出
                System.out.print(Integer.toHexString(b)+" ");
            }//for

            randomAccessFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
public class FileDemo {

    public static void main(String[] args) {
        String pathname = "D:\\Recommended system.txt";
        // 建立檔案例項
        File file = new File(pathname);

        try {
            // 判斷檔案是否存在
            if(!file.exists()){
                file.createNewFile();
            }//if

            // 讀寫方式開啟檔案
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");

            // 寫值
            for(int i = 0;i < 5;++i){
                randomAccessFile.writeInt(i);
            }//for

            // 將檔案指標移到第二個Int值後
            randomAccessFile.seek(2*4);
            // 覆蓋第三個Int值
            randomAccessFile.writeInt(6);

            // 檔案指標指向檔案開頭
            randomAccessFile.seek(0);
            // 輸出
            for (int i = 0;i < 5;++i) {
                System.out.print(randomAccessFile.readInt()+" ");
            }//for

            randomAccessFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


    package com.qunar.bean;
import java.io.File;
import java.io.RandomAccessFile;
public class FileDemo {

    public static void main(String[] args) {
        String pathname = "D:\\Recommended system.txt";
        // 建立檔案例項
        File file = new File(pathname);

        try {
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");  

            // 以下向file檔案中寫資料  
            // 佔4個位元組  
            randomAccessFile.writeInt(2015);
            // 佔8個位元組
            randomAccessFile.writeDouble(12.23);  
            // 佔2個位元組
            randomAccessFile.writeShort(19);  
            System.out.println("當前位置:"+randomAccessFile.getFilePointer());
            randomAccessFile.writeUTF("歡迎來到小斯的部落格");
            System.out.println("當前位置:"+randomAccessFile.getFilePointer());
            // 佔2個位元組
            randomAccessFile.writeChar('Y');  
            System.out.println("當前位置:"+randomAccessFile.getFilePointer());
            randomAccessFile.writeUTF("小斯的部落格歡迎你");

            // 把檔案指標位置設定到檔案起始處  
            randomAccessFile.seek(0);
            System.out.println("讀取一個Int值:"+randomAccessFile.readInt());  
            System.out.println("讀取一個Double值:"+randomAccessFile.readDouble());  
            System.out.println("讀取一個Short值:"+randomAccessFile.readShort()); 
            System.out.println("讀取一個字串:"+randomAccessFile.readUTF());  
            // 將檔案指標跳過2個位元組
            randomAccessFile.skipBytes(2);  
            System.out.println("讀取一個字串:"+randomAccessFile.readUTF());  

            randomAccessFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

相關文章