RandomAccessFile 类是专门处理文件的字节流,与其他文件类不同、也是此类最大的特点是:该类支持对文件的随机访问。
RandomAccessFile 维护着一个偏移量,也叫文件指针。
当你用 RandomAccessFile 打开一个文件时,指针的值为 0
读取文件时,指针就会自动向前移动,每读取一个字节,指针就 +1
写入文件时也一样,每写入一个字节,指针就 +1
可以通过 getFilePointer 方法 获取指针,通过 seek 方法设置指针
读取和写入
读取
public static void main(String[] args) throws IOException{
// word.txt 文件只有 abc,utf-8格式
// "rw" 是打开读和写的权限,具体构造方法可以参考 API 文档
RandomAccessFile rw = new RandomAccessFile("E:/xp/test/word.txt", "rw");
// 获取指针
System.out.println("当前指针:" + rw.getFilePointer());
int read = rw.read();
System.out.println("读取结果:" + read);
System.out.println("当前指针:" + rw.getFilePointer());
}
运行结果如下:
当前指针:0
读取结果:97
当前指针:1
可以看到读取一个字节后,指针自动向后偏移了一位
为什么读取出来不是 a 而是 97呢?
上面说过了,因为 RandomAccessFile 是字节流,读和写都是以字节为单位,在 java 中,byte 占 1 个字节,一个字节的长度是 8 位,byte 的取值范围是 -128 到 127,a 对应的是 97,所以读取结果是 97。
写入
public static void main(String[] args) throws IOException{
// word.txt 文件只有 abc
RandomAccessFile rw = new RandomAccessFile("E:/xp/test/word.txt", "rw");
// 获取指针
System.out.println("当前指针:" + rw.getFilePointer());
rw.write("d".getBytes());
System.out.println("当前指针:" + rw.getFilePointer());
}
运行结果:
当前指针:0
当前指针:1
可以看到写入时,指针也向后偏移了一位。
这时候文件里的内容变成了 dbc,并不是 abcd,说明 RandomAccessFile 写入文件时是以覆盖的形式写入的,因为开始的指针是 0,写入时是在 0 处写入的,所以 a 被 c 覆盖了。
追加写入
如果是要追加写入,可以先获取文件的字节大小,然后设置指针值再写入。
public static void main(String[] args) throws IOException{
// word.txt 文件只有 abc
RandomAccessFile rw = new RandomAccessFile("E:/xp/test/word.txt", "rw");
// 获取指针
System.out.println("当前指针:" + rw.getFilePointer());
// 设置指针为文件的长度
rw.seek(rw.length());
rw.write("d".getBytes());
System.out.println("当前指针:" + rw.getFilePointer());
}
运行结果:
当前指针:0
当前指针:4
这时候文件里的内容是:abcd
RandomAccessFile 还有更多实用的方法,如何使用可以参考 API 文档
这里就不一一踩坑了,用到的时候再翻文档吧~