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 文档

这里就不一一踩坑了,用到的时候再翻文档吧~

原文链接:https://miansen.wang/2019/06/27/1/