RandomAccessFile 是 Java 中支持随机读写的专用类,通过 seek() 移动指针、readXxx()/writeXxx() 操作数据,并需注意字节对齐、模式选择、线程安全及资源关闭。

传统IO流(如 FileInputStream 和 FileOutputStream)是单向、顺序的,不支持在同一个流对象上同时读写,也无法直接跳转到文件任意位置进行修改。要实现随机读写,必须换用支持定位操作的类——RandomAccessFile 是 Java 中专为此设计的标准解决方案。
用 RandomAccessFile 替代传统流
RandomAccessFile 既不是输入流也不是输出流的子类,它独立封装了文件指针和读写能力,允许随时移动位置、混合读写:
- 构造时指定模式:
"r"(只读)、"rw"(读写),后者才能修改文件内容 - 用
seek(long pos)移动文件指针到指定字节偏移量(从0开始) - 调用
readXxx()或writeXxx()方法在当前位置执行操作 - 用
getFilePointer()查看当前读写位置,便于调试或逻辑控制
注意数据类型与字节对齐
随机读写不是“按行”或“按字符串”,而是严格按字节偏移。如果存的是基本类型(如 int、double)或自定义结构,必须保证每次读写的字节数一致,否则会错位:
- 例如:用
writeInt(123)写入一个 int(占4字节),之后必须用readInt()读取,且指针位置需对齐 - 字符串建议用
writeUTF(String)+readUTF(),它们自带长度前缀,比writeBytes()更安全 - 若混用文本与二进制数据,需自行记录每段起始位置,避免覆盖或解析错误
配合 NIO 的 MappedByteBuffer(进阶选择)
对于大文件高频随机访问,RandomAccessFile 的 I/O 开销仍较高。可借助 NIO 将文件映射为内存块:
- 通过
raf.getChannel().map(...)获取MappedByteBuffer - 支持
get()/put()随机字节访问,性能接近内存操作 - 注意:映射区域大小固定,修改后需调用
force()确保写入磁盘;不适用于超大文件(受虚拟内存限制)
避免常见陷阱
使用过程中容易忽略的关键细节:
- 文件不存在时,
"rw"模式会自动创建;但"r"模式会抛FileNotFoundException - 写入超出当前文件长度时,中间空洞会被填充为0字节(Linux/Unix 行为),并非所有系统表现一致
- 多线程访问同一
RandomAccessFile实例需手动同步,它本身不保证线程安全 - 用完务必调用
close(),否则可能造成文件句柄泄漏或数据未落盘

















