ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
### 读写随机访问文件 使用 `RandomAccessFile` 就像是使用了一个 `DataInputStream` 和 `DataOutputStream` 的结合体(因为它实现了相同的接口:`DataInput` 和 `DataOutput`)。另外,我们还可以使用 `seek()` 方法移动文件指针并修改对应位置的值。 在使用 `RandomAccessFile` 时,你必须清楚文件的结构,否则没法正确使用它。`RandomAccessFile` 有一套专门的方法来读写基本数据类型的数据和 UTF-8 编码的字符串: ```java // iostreams/UsingRandomAccessFile.java import java.io.*; public class UsingRandomAccessFile { static String file = "rtest.dat"; public static void display() { try ( RandomAccessFile rf = new RandomAccessFile(file, "r") ) { for (int i = 0; i < 7; i++) System.out.println( "Value " + i + ": " + rf.readDouble()); System.out.println(rf.readUTF()); } catch (IOException e) { throw new RuntimeException(e); } } public static void main(String[] args) { try ( RandomAccessFile rf = new RandomAccessFile(file, "rw") ) { for (int i = 0; i < 7; i++) rf.writeDouble(i * 1.414); rf.writeUTF("The end of the file"); rf.close(); display(); } catch (IOException e) { throw new RuntimeException(e); } try ( RandomAccessFile rf = new RandomAccessFile(file, "rw") ) { rf.seek(5 * 8); rf.writeDouble(47.0001); rf.close(); display(); } catch (IOException e) { throw new RuntimeException(e); } } } ``` 输出结果: ``` Value 0: 0.0 Value 1: 1.414 Value 2: 2.828 Value 3: 4.242 Value 4: 5.656 Value 5: 7.069999999999999 Value 6: 8.484 The end of the file Value 0: 0.0 Value 1: 1.414 Value 2: 2.828 Value 3: 4.242 Value 4: 5.656 Value 5: 47.0001 Value 6: 8.484 The end of the file ``` `display()` 方法打开了一个文件,并以 `double` 值的形式显示了其中的七个元素。在 `main()` 中,首先创建了文件,然后打开并修改了它。因为 `double` 总是 8 字节长,所以如果要用 `seek()` 定位到第 5 个(从 0 开始计数) `double` 值,则要传入的地址值应该为 `5*8`。 正如前面所诉,虽然 `RandomAccess` 实现了 `DataInput` 和 `DataOutput` 接口,但实际上它和 I/O 继承体系中的其它部分是分离的。它不支持装饰,故而不能将其与 `InputStream` 及 `OutputStream` 子类中的任何一个组合起来,所以我们也没法给它添加缓冲的功能。 该类的构造器还有第二个必选参数:我们可以指定让 `RandomAccessFile` 以“只读”(r)方式或“读写” (rw)方式打开文件。 除此之外,还可以使用 `nio` 中的“内存映射文件”代替 `RandomAccessFile`,这在[附录:新 I/O](Appendix-New-IO.md)中有介绍。