文件的随机访问主要是通过RandomAccessFile来完成,它使用seek()方法从文件中的一个记录移动到下一个记录进行读或者写,而不需要知道总共多少个记录。它不需要把所有的记录全部装进内存再进行读写,对于访问大文件来说,这是一种高效的选择。
构造函数:两种方法来制定对应的文件:字符串路径和File
构造方法摘要 | |
---|---|
RandomAccessFile(File file, String mode) 创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。 | |
RandomAccessFile(String name, String mode) 创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。 |
常用方法:
方法摘要 | |
---|---|
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 编码以与机器无关的方式将一个字符串写入该文件。 |
测试程序:将4条person数据按照一定的格式(各字段定长写入到文件),然后随机遍历整个文件,输出所有的记录。然后找到包含关键字的的记录。
package FileOperation;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
public class FileRandomAccess {
/** 姓名在文件中的长度 */
public static final int NAME_LENGTH = 100;
/** 年龄在文件中的长度 */
public static final int INT_LENGTH = 8;
public static final int DESCRIPTION_LENGTH = 200;
/** 每条 Person 记录在文件中的长度 */
public static final int PERSON_LENGTH = NAME_LENGTH + INT_LENGTH + DESCRIPTION_LENGTH;
//Person内部类
static class Person{
public String name;
public int age;
public String description;
public Person(String name, int age, String description){
this.name = name;
this.age = age;
this.description = description;
}
public String toString(){
return "Person[name=\"" + name + "\", age=\"" + age + "\", description=\"" + description + "\"]";
}
}
//定义一个Person类型的数组
static Person[] person = new Person[] {
new Person("杜甫", 45, "唐朝现实主义诗人"),
new Person("爱因斯坦", 20, "伟大的物理学家,提出相对论理论。"),
new Person("李白", 20, "唐朝浪漫主义诗人"),
new Person("曹雪芹", 47, "《红楼梦》作者"),
};
//main函数
public static void main(String[] args) throws IOException{
//构造一个随机访问类的file对象
RandomAccessFile file = new RandomAccessFile("C:\\person.dat", "rw");
// 初始化数据 根据初始化数据设置文件长度
file.setLength(person.length * PERSON_LENGTH);
for(int i=0; i<person.length; i++){
writePerson(file, person[i]);//调用writePerson
}
System.out.println("\r\n列出文件中所有的数据:");
Person[] allPersons = listAllPerson(file);//调用listAllPerson返回一个person数组
for(int i=0; i<allPersons.length; i++){
System.out.println(allPersons[i]);
}
System.out.println("\r\n在文件中查找关键字 雪,结果如下:");
Person p = findPerson(file, "雪");//调用findPerson查找file里的keyword
System.out.println("找到结果:" + p);
file.close();
}
// 写 String 类型数据,要注意写String和写int的区别,
public static void writeString(RandomAccessFile file, String name, int fieldLength) throws IOException{
file.writeUTF(name);
int length = name.getBytes("UTF-8").length;
file.skipBytes(fieldLength - length);//跳过没有用完的字节,保持对齐
}
// 写 int 类型数据
public static void writeInt(RandomAccessFile file, int age) throws IOException{
file.writeInt(age);
}
//写person对象(写 String,写 int )
public static void writePerson(RandomAccessFile file, Person person) throws IOException{
writeString(file, person.name, NAME_LENGTH);
writeInt(file, person.age);
writeString(file, person.description, DESCRIPTION_LENGTH);
}
// 读 String 类型数据
public static String readString(RandomAccessFile file, int fieldLength) throws IOException{
String name = file.readUTF();
int length = name.getBytes("UTF-8").length;
file.skipBytes(fieldLength - length);
return name;
}
// 读 int 类型数据
public static int readInt(RandomAccessFile file) throws IOException{
return file.readInt();
}
//读person对象(读 String,读 int)
public static Person readPerson(RandomAccessFile file) throws IOException {
// 找到文件头了
if(file.getFilePointer() >= file.length()){
return null;
}
return new Person(
readString(file, NAME_LENGTH), // name
readInt(file), // age
readString(file, DESCRIPTION_LENGTH) // description
);
}
// 列出数据文件中的所有的数据
public static Person[] listAllPerson(RandomAccessFile file) throws IOException {
List list = new ArrayList();
file.seek(0);
while(true){
Person person = readPerson(file);
if(person == null)
break;
list.add(person);
}
Person[] person = new Person[list.size()];
list.toArray(person);
return person;
}
// 查找符合条件的数据
public static Person findPerson(RandomAccessFile file, String keyword) throws IOException {
// 从开始寻找记录
file.seek(0);
while(true){
Person person = readPerson(file);//每次读一个person,注意每次seek都要往后移动
if(person == null)
break;
if(person.name.contains(keyword)){
return person;
}
}
return null;
}
}
运行结果:
列出文件中所有的数据:
Person[name="杜甫", age="45", description="唐朝现实主义诗人"]
Person[name="爱因斯坦", age="20", description="伟大的物理学家,提出相对论理论。"]
Person[name="李白", age="20", description="唐朝浪漫主义诗人"]
Person[name="曹雪芹", age="47", description="《红楼梦》作者"]
在文件中查找关键字 雪,结果如下:
找到结果:Person[name="曹雪芹", age="47", description="《红楼梦》作者"]