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();
}
}
}
~~~
- 前言
- [Hibernate開發之路](1)Hibernate配置
- [Hibernate開發之路](2)Hibernate問題
- [Hibernate開發之路](3)基礎配置
- [Hibernate開發之路](4)ID生成策略
- [Hibernate開發之路](5)聯合主鍵
- [設計模式實踐之路](1)單例模式
- [Java]UDP通信的簡單例子
- [Java]套接字地址InetAddress講解
- [Java開發之路](1)final關鍵字
- [Java開發之路](2)Java字符串
- [Java開發之路](3)Java常用類
- [Java開發之路](4)String、StringBuffer與StringBuilder詳解
- [Java開發之路](5)異常詳解
- [Java開發之路](6)File類的使用
- [Java開發之路](7)RandomAccessFile類詳解
- [Java開發之路](8)輸入流和輸出流
- [Java開發之路](9)對象序列化與反序列化
- [Java開發之路](10)DOM解析XML文檔
- [Java開發之路](11)SAX解析XML文檔
- [Java開發之路](12)JDOM和DOM4J解析XML文檔
- [Java開發之路](14)反射機制
- [Java開發之路](15)注解
- [Java開發之路](16)學習log4j日志
- [Java開發之路](18)關于Class.getResource和ClassLoader.getResource的路徑問題
- [Java開發之路](19)Long緩存問題
- [Java開發之路](20)try-with-resource 異常聲明
- [Java開發之路](21)Comparator與Comparable
- [Java]Java工程師成神之路
- [細說Java](1)圖說字符串的不變性
- [細說Java](2)Java中字符串為什么是不可變的
- [細說Java](3)創建字符串是使用&quot; &quot;還是構造函數?