java编程笔记16 随机访问文件类RandomAccessFile
文件的随机访问主要是通过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="《红楼梦》作者"]