# 随机访问文件

> 原文： [https://docs.oracle.com/javase/tutorial/essential/io/rafs.html](https://docs.oracle.com/javase/tutorial/essential/io/rafs.html)

_ 随机存取文件 _ 允许对文件内容进行非顺序或随机访问。要随机访问文件，请打开文件，查找特定位置，以及读取或写入该文件。

使用 [`SeekableByteChannel`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html) 接口可以实现此功能。 `SeekableByteChannel`接口使用当前位置的概念扩展通道 I / O.使用方法可以设置或查询位置，然后可以从该位置读取数据或将数据写入该位置。 API 由一些易于使用的方法组成：

*   [`position`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html#position--) - 返回通道的当前位置
*   [`position(long)`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html#position-long-) - 设置通道的位置
*   [`read(ByteBuffer)`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html#read-java.nio.ByteBuffer-) - 从通道读取缓冲区的字节
*   [`write(ByteBuffer)`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html#write-java.nio.ByteBuffer-) - 将缓冲区中的字节写入通道
*   [`truncate(long)`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html#truncate-long-) - 截断连接到频道的文件（或其他实体）

[使用通道 I / O 读取和写入文件](file.html#channelio)显示`Path.newByteChannel`方法返回`SeekableByteChannel`的实例。在默认文件系统上，您可以按原样使用该通道，也可以将其转换为 [`FileChannel`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/FileChannel.html) ，以便访问更高级的功能，例如将文件区域直接映射到内存中更快的访问，锁定文件的一个区域，或从绝对位置读取和写入字节，而不会影响通道的当前位置。

以下代码段使用`newByteChannel`方法之一打开用于读取和写入的文件。返回的`SeekableByteChannel`被强制转换为`FileChannel`。然后，从文件的开头读取 12 个字节，字符串“我在这里！”是在那个地方写的。文件中的当前位置移动到末尾，并附加从开头的 12 个字节。最后，字符串，“我在这里！”附加，并关闭文件上的通道。

```
String s = "I was here!\n";
byte data[] = s.getBytes();
ByteBuffer out = ByteBuffer.wrap(data);

ByteBuffer copy = ByteBuffer.allocate(12);

try (FileChannel fc = (FileChannel.open(file, READ, WRITE))) {
    // Read the first 12
    // bytes of the file.
    int nread;
    do {
        nread = fc.read(copy);
    } while (nread != -1 && copy.hasRemaining());

    // Write "I was here!" at the beginning of the file.
    fc.position(0);
    while (out.hasRemaining())
        fc.write(out);
    out.rewind();

    // Move to the end of the file.  Copy the first 12 bytes to
    // the end of the file.  Then write "I was here!" again.
    long length = fc.size();
    fc.position(length-1);
    copy.flip();
    while (copy.hasRemaining())
        fc.write(copy);
    while (out.hasRemaining())
        fc.write(out);
} catch (IOException x) {
    System.out.println("I/O Exception: " + x);
}

```