透過前面的學習我們知道,如果準備讀取文件,需要建立指向該文件的輸入流;如果準備寫文件,需要建立指向該文件的輸出流。那麼,能否建立一個流,透過該流既能讀文件也能寫文件呢?這正是本節要介紹的隨機流。
RandomAccessFile類別所建立的流稱做隨機流,與前面的輸入、輸出流不同的是,RandomAccessFile類別既不是InputStream類別的子類,也不是OutputStream類別的子類。但是RandomAccessFile類別所建立的流的指向既可以作為流的來源,也可以作為流的目的地,換句話說,當準備對一個文件進行讀寫操作時,創建一個指向該文件的隨機流即可,這樣既可以從這個流讀取檔案中的數據,也可以透過這個流寫入資料到檔案。
以下是RandomAccessFile類別的兩個建構方法:
參數name用來決定一個檔名,給出所建立的流的來源,也是流目的地。參數mode取r(唯讀)或rw(可讀寫),決定建立的流對檔案的存取權利。
參數file是一個File對象,給出創建的流的來源,也是流目的地。參數mode取r(唯讀)或rw(可讀寫),決定建立的流對檔案的存取權利。
注意:RandomAccessFile流指向檔案時,不刷新檔案。
RandomAccessFile類別中有一個方法seek(long a)用來定位RandomAccessFile流的讀寫位置,其中參數a決定讀寫位置距離檔案開頭的位元組數。另外流還可以呼叫getFilePointer()方法來取得流的目前讀寫位置。 RandomAccessFile流對檔案的讀寫比順序讀寫更有彈性。
例如,把幾個int型整數寫入到一個名字為tom.dat檔案中,然後再以相反順序讀出這些資料:
importjava.io.*;publicclassMain{publicstaticvoidmain(Stringargs[]){RandomAccessFileinAndOut=null;intdata[]={1,2,3,4,5,6,7,8,9,10};try{inAndOut=newRandomAccessFile (tom.dat,rw);for(inti=0;i<data.length;i++){inAndOut.wr iteInt(data[i]);}for(longi=data.length-1;i>=0;i--){inAndOut.seek(i*4);System.out.printf(t%d,inAndOut .readIn t());/*一個int型資料佔4個位元組,inAndOut從檔案的第36個位元組讀取最後面的一個整數,每隔4個位元組往前讀取一個整數*/}inAndOut .close();}catch(IOExceptione){}}}
RandomAccessFile流常用的方法如下:
注意:RandomAccessFile流的readLine()方法在讀取含有非ASCⅡ字元的文件時,例如含有漢字的文件,會出現「亂碼」現象。因此,需要把readLine()讀取的字串用「iso-8859-1」編碼重新編碼存放到byte數組中,然後再用當前機器的預設編碼將該數組轉換為字串,操作如下:
Stringstr=in.readLine();
byteb[]=str.getBytes(iso-8859-1);
Stringcontent=newString(b);
如果機器的預設編碼是“GB2312”,那麼
Stringcontent=newString(b);
等同於
Stringcontent=newString(b,GB2312);
例如:
importjava.io.*;publicclassMain{publicstaticvoidmain(Stringargs[]){RandomAccessFilein=null;try{in=newRandomAccessFile(Main.java,rw);longlength=in.length();//取得檔案的長度longposition=0; in.seek(positi on);//將讀取位置定位到檔案的起始while(position<length){Stringstr=in.readLine();byteb[]=str.getBytes(iso-8859-1);str=newString(b );position=in.getFilePointer();System.out.println(str);}}catch(IOExceptione){}}}