RandomAccessFile是Java中实现文件随机读写的核心类,支持通过seek()定位任意字节位置、getFilePointer()获取指针、setLength()管理长度,提供基本类型读写方法,适用于大文件分块处理、断点续传及二进制协议解析等场景。

Java 中实现文件的随机访问,核心是使用 RandomAccessFile 类。它允许在文件任意位置读取或写入数据,不依赖流式顺序处理,适合需要跳转、修改中间内容、或模拟数据库记录存取等场景。
RandomAccessFile 的基本用法
该类同时实现 DataInput 和 DataOutput 接口,既能读也能写,需指定打开模式:
- "r":只读,文件必须存在,否则抛出 FileNotFoundException
- "rw":读写,文件不存在则创建;存在则保留原内容,可覆盖任意位置
- "rws" 和 "rwd":支持同步写入(如日志、事务性操作),确保元数据或内容真正落盘
示例:打开文件并定位到第 100 字节开始读一个 int
try (RandomAccessFile raf = new RandomAccessFile("data.bin", "r")) {
raf.seek(100); // 移动文件指针到字节偏移 100
int value = raf.readInt(); // 从该位置读取 4 字节作为 int
}
定位与指针操作的关键方法
文件指针(file pointer)决定下一次读写的位置,控制它就实现了“随机”:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- seek(long pos):将指针设为从文件开头起的绝对字节位置(支持正向跳转,也支持回到前面)
- getFilePointer():获取当前指针位置,便于记录或调试
- length():返回文件总字节数,常用于边界判断(例如避免 seek 超出末尾)
注意:seek(0) 是回到开头;seek(length()) 是定位到末尾(此时 write 会追加,但 read 会触发 EOFException)。
读写结构化数据的实用技巧
RandomAccessFile 常用于固定长度记录(如学生成绩、传感器采样点),每条记录占 N 字节:
- 定义好记录格式(比如:id:int + name:char[20] + score:double)
- 计算第 n 条记录起始位置:n × 记录字节数,再 seek 过去读写
- 写字符串时建议用 writeBytes(String)(按 ISO-8859-1 编码)或手动转 byte[];读字符串需配合固定长度和编码解析
- 避免混用 readLine()(已废弃且依赖换行符)——它破坏二进制随机访问的确定性
注意事项与替代方案
RandomAccessFile 是传统 I/O 工具,有其局限性:
- 不支持字符编码自动转换(如 UTF-8),处理文本需自行编码/解码
- 不是 NIO Channel,无法直接用于 Selector 多路复用
- 若需更现代的随机访问能力,可考虑 FileChannel 配合 MappedByteBuffer(内存映射),适合超大文件高频随机读写
- 并发访问需外部同步(它本身不保证线程安全)
简单随机读写首选 RandomAccessFile;高吞吐或大数据量场景,再评估 FileChannel + MappedByteBuffer 方案。

















