Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

    • Java IO概述
    • IO基础

    • 常用IO流

    • 文件与目录操作

    • Java NIO

    • 高级主题

      • RandomAccessFile
        • 1. 基本用法
        • 2. 文件指针
        • 3. 修改指定位置内容
        • 4. 文件追加
        • 5. 与 FileChannel 的关系
        • 6. 适合场景
        • 专家实践清单
        • Tips 快问快答
        • 7. 总结
      • 内存映射文件MappedByteBuffer
      • 零拷贝
      • BIO-NIO-AIO模型
      • 字符集与乱码
      • 序列化安全与替代方案
    • 实践与性能优化

    • 面试与设计题

    • IO实践速查

  • JVM

目录

RandomAccessFile

RandomAccessFile 支持对文件进行随机访问。和普通流只能顺序读写不同,它可以移动文件指针,在指定位置读取或写入。

# 1. 基本用法

try (RandomAccessFile file = new RandomAccessFile("data.dat", "rw")) {
    file.writeInt(100);
    file.writeUTF("hello");

    file.seek(0);
    int value = file.readInt();
    String text = file.readUTF();
}

构造模式:

  • "r":只读。
  • "rw":读写。
  • "rws":读写,并尽量同步内容和元数据。
  • "rwd":读写,并尽量同步内容。

# 2. 文件指针

RandomAccessFile 维护一个文件指针。

long pointer = file.getFilePointer();
file.seek(1024);

每次读写都会推动指针移动。seek 可以跳到任意位置。

# 3. 修改指定位置内容

try (RandomAccessFile file = new RandomAccessFile("data.dat", "rw")) {
    file.seek(8);
    file.writeInt(999);
}

这适合修改固定长度记录。如果记录长度不固定,直接覆盖可能破坏后续数据。

# 4. 文件追加

try (RandomAccessFile file = new RandomAccessFile("app.log", "rw")) {
    file.seek(file.length());
    file.write("new line\n".getBytes(StandardCharsets.UTF_8));
}

不过普通追加日志通常使用 FileOutputStream(file, true) 或日志框架更合适。

# 5. 与 FileChannel 的关系

RandomAccessFile 可以获取对应的 FileChannel:

try (RandomAccessFile file = new RandomAccessFile("data.dat", "rw");
     FileChannel channel = file.getChannel()) {
    // use channel
}

FileChannel 提供了更现代的 NIO 能力,如内存映射、文件锁、通道传输。

# 6. 适合场景

  • 固定长度记录文件。
  • 断点续传。
  • 文件分片下载。
  • 简单索引文件。
  • 需要从文件中间读写的场景。

不适合:

  • 可变长度复杂记录。
  • 高并发写入同一个文件。
  • 需要事务语义的数据存储。

这些场景应该考虑数据库、日志结构存储或成熟文件格式。

# 专家实践清单

场景 是否适合 说明
固定格式文件 适合 可按偏移读写字段
断点续传 适合 可 seek 到指定位置
大文件随机读取 适合 避免从头顺序扫描
高并发事务写入 不适合 缺少事务和并发控制
复杂索引存储 谨慎 更适合数据库或专用存储

随机访问模型:

文件字节序列
  ├─ offset=0
  ├─ offset=1024
  └─ offset=N

seek(offset) -> read/write

# Tips 快问快答

Q:RandomAccessFile 解决什么问题? A:按文件偏移位置随机读写,而不是只能顺序读写。

Q:seek 的作用是什么? A:移动文件指针到指定偏移位置。

Q:RandomAccessFile 是 InputStream 吗? A:不是,它是独立类,但提供读写基本类型和字节的方法。

Q:模式 r 和 rw 有什么区别? A:r 只读,rw 可读写并可能创建文件。

Q:随机写文件是否自动保证线程安全? A:不保证,多线程写同一文件需要外部同步或分区设计。

Q:它适合做数据库吗? A:不适合直接当数据库,需要索引、事务、恢复和并发控制等大量机制。

Q:和 FileChannel 有什么关系? A:可以通过 getChannel() 获取底层 FileChannel。

Q:最常见的错误是什么? A:偏移计算错误、覆盖错误位置、并发写入没有协调。

# 7. 总结

RandomAccessFile 是顺序流之外的重要补充,适合按位置读写文件。它简单直接,但缺少高级并发和事务能力。复杂场景中通常会结合 FileChannel 或更专业的存储组件使用。

上次更新: 2026/06/25, 14:19:18
NIO与IO对比
内存映射文件MappedByteBuffer

← NIO与IO对比 内存映射文件MappedByteBuffer→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式