1.5 RandomAccessFile类:动态读取文件内容
所謂動(dòng)態(tài)讀取是指從文件的任意位置開始訪問文件,而不是必須從文件開始位置讀取到文件末尾。動(dòng)態(tài)讀取需要用到 Java 中的 RandomAccessFile 類。
RandomAccessFile 是 Java 輸入/輸出流體系中功能最豐富的文件內(nèi)容訪問類,它提供了眾多的方法來訪問文件內(nèi)容,它既可以讀取文件內(nèi)容,也可以向文件輸出數(shù)據(jù)。由于 RandomAccessFile 可以從任意位置訪問文件,所以在只需要訪問文件部分內(nèi)容的情況下,使用 RandonAccessFile 類是一個(gè)很好的選擇。
RandomAccessFile 對象包含了一個(gè)記錄指針,用以標(biāo)識(shí)當(dāng)前讀寫處的位置,當(dāng)程序新創(chuàng)建一個(gè) RandomAccessFile 對象時(shí),該對象的文件記錄指針位于文件頭(也就是 0 處),當(dāng)讀/寫了 n 個(gè)字節(jié)后,文件記錄指針將會(huì)向后移動(dòng) n 個(gè)字節(jié)。除此之外,RandonAccessFile 可以自由移動(dòng)該記錄指針,既可以向前移動(dòng),也可以向后移動(dòng)。
RandomAccessFile 類中提供了一些常用讀取和寫入數(shù)據(jù)的方法,如表 1 所示。
| boolean readBoolean() | 從文件中讀取一個(gè) boolean 值 |
| byte readByte() | 從文件中讀取一個(gè)帶符號位的字節(jié) |
| char readChar() | 從文件中讀取一個(gè)字符 |
| int readlnt() | 從文件中讀取一個(gè)帶符號位的整數(shù) |
| long readLong() | 從文件中讀取一個(gè)帶符號位的 long 值 |
| String readLine() | 從文件中讀取下一行文本 |
| void seek(long pos) | 指定從文件起始位置開始的指針偏移量 |
| void writeBoolean(boolean v) | 以字節(jié)的形式向文件中寫入一個(gè) boolean 值 |
| void writeByte(int v) | 以單字節(jié)的形式向文件中寫入一個(gè) byte 值 |
| void writeChar(int v) | 以雙字節(jié)的形式向文件中寫入一個(gè) char 值 |
| void writelnt(int v) | 以4字節(jié)的形式向文件中寫入一個(gè)整數(shù) |
| writeLong(long v) | 以8字節(jié)的形式向文件中寫入一個(gè) long 值 |
| void writeBytes(String s) | 以字節(jié)序列的形式向文件中寫入一個(gè)字符串 |
| void skipBytes(int n) | 以當(dāng)前文件指針位置為起始點(diǎn),跳過 n 字節(jié) |
RandomAccessFile 類的構(gòu)造方法有如下兩種重載形式。
注意:如果使用 rw 方式聲明 RandomAccessFile 對象時(shí),要寫入的文件不存在,系統(tǒng)將自動(dòng)進(jìn)行創(chuàng)建。
例 1
編寫一個(gè)程序,使用 RandomAccessFileDemo 類創(chuàng)建一個(gè) words.txt 文件,然后寫入一個(gè)長中文字符串,再從第 6 個(gè)字節(jié)開始讀取并輸出。
1)創(chuàng)建一個(gè) RandomAccessFileDemo 類對象。在 main() 方法中創(chuàng)建到 H:\JavaCodes\words.txt 的 File 對象,如果該文件已經(jīng)存在則先刪除再創(chuàng)建,代碼如下所示。
public class RandomAccessFileDemo {public static void main(String[] args) {File file = new File("H:\\myJava\\words.txt"); // 指定文件路徑if (file.exists()) { // 判斷文件是否存在file.delete();}try {file.createNewFile();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}2)創(chuàng)建 RandomAccessFile 對象,以讀寫方式操作 File 對象。定義一個(gè)要寫入的字符串,再將其進(jìn)行格式的轉(zhuǎn)換。這樣是為了使其寫入文件的內(nèi)容不出現(xiàn)亂碼,再將轉(zhuǎn)換后的內(nèi)容寫入文件,代碼如下所示。
import java.io.File; import java.io.IOException; import java.io.RandomAccessFile;public class RandomAccessFileDemo {public static void main(String[] args) throws IOException {File file = new File("H:\\myJava\\words.txt"); // 指定文件路徑if (f.exists()) // 判斷文件是否存在{f.delete(); // 存在則先刪除}f.createNewFile(); // 再創(chuàng)建RandomAccessFile raf = new RandomAccessFile(f,"rw");String str1 = "晴天,陰天,多云,小雨,大風(fēng),中雨,小雪,雷陣雨"; // 要寫入的字符串String str2 = new String(str1.getBytes("GBK"),"ISO-8859-1"); // 編碼轉(zhuǎn)換raf.writeBytes(str2); //寫入文件} }3)打印出當(dāng)前指針的位置,然后將其移動(dòng)到第 6 個(gè)字節(jié)。再定義一個(gè)長度為 2 的 byte 數(shù)組,然后開始進(jìn)行內(nèi)容的循環(huán)讀取,將讀出的內(nèi)容以字符串的形式輸出到控制臺(tái),代碼如下所示。
System.out.println("當(dāng)前文件指針的位置:" + raf.getFilePointer()); raf.seek(6); // 移動(dòng)文件指針 System.out.println("從文件頭跳過6個(gè)字節(jié),現(xiàn)在文件內(nèi)容如下:"); byte[] buffer = new byte[2]; int len = 0; while ((len = raf.read(buffer, 0, 2)) != -1) {System.out.print(new String(buffer, 0, len)); // 輸出文件內(nèi)容 }4)運(yùn)行程序,程序運(yùn)行結(jié)果如下所示,顯示了寫入字符串后指針的位置,以及從文件開關(guān)跳過 6 個(gè)字節(jié)后讀取到的字符串,圖 1 為寫入文件中的字符串內(nèi)容。
當(dāng)前文件指針的位置:48 從文件頭跳過6個(gè)字節(jié),現(xiàn)在文件內(nèi)容如下: 陰天,多云,小雨,大風(fēng),中雨,小雪,雷陣雨
對比輸出結(jié)果和圖 1 發(fā)現(xiàn),中文字符串已成功寫入記事本中,但是讀出的字符串內(nèi)容少了兩個(gè)字和一個(gè)逗號,這是由于使用 RandomAccessFile 的 seek() 方法跳過了前 6 字節(jié)(1 個(gè)漢字占兩字節(jié))。在本程序中將中文字符串進(jìn)行了編碼轉(zhuǎn)換,然后再寫入文件。讀取時(shí)調(diào)用的是帶有 3 個(gè)參數(shù)的 read() 方法將記事本中的內(nèi)容讀取出來。
注意:要寫進(jìn)文本的內(nèi)容是中文,如果不進(jìn)行字符的轉(zhuǎn)換,寫進(jìn)去的會(huì)是亂碼,讀取出來的內(nèi)容也會(huì)是亂碼。
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的1.5 RandomAccessFile类:动态读取文件内容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.4 File类(文件操作类)获取文件
- 下一篇: 1.10 对象序列化控制输入输出