欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Java NIO 简例】FileChannel

程序员文章站 2022-03-07 19:20:37
...

注:利用 FileChannel.transferTo 和 FileChannel.transferFrom 方法可以更高效地读写文件。

(《FileChannel 数据传输》)

 

原文:《Java NIO FileChannel

Java NIO 中的 FileChannel 可用于读写文件。FileChannel 总是以 阻塞 模式运行,不支持非阻塞模式。

 

开启 FileChannel

可通过调用 FileInputStream、FileOutputStream 或 RandomAccessFile 的 getChannel() 方法来获得 FileChannel

RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
FileChannel channel = aFile.getChannel();

也可通过调用 FileChannel 的静态方法 open(Path, OpenOption...) 或 open(Path, Set<? extends OpenOption>, FileAttribute<?>...) 开启

 

读取 FileChannel 中的数据

通常可调用 FileChannel 的 read(ByteBuffer) 方法将数据从channel的当前位置开始,读取到 buffer 中。
如果返回值为 -1,则表示已读到文件末尾。

ByteBuffer buffer = ByteBuffer.allocate(1024);
int readByteCount = channel.read(buffer);

 

其它方法:

  • read(ByteBuffer, long) 可以指定读取channel的位置,但不会改变 channel 当前位置。
  • read(ByteBuffer[]) 和 read(ByteBuffer[], int, int) 属于 ScatteringByteChannel 的 数据分散 特性。

 

向 FileChannel 写数据

通常可调用 FileChannel 的 write(ByteBuffer) 方法将 buffer 当前位置开始的数据写入channel。

返回值表示本次写入 channel 的字节数,可能为0。所以需要放在while循环中,确保 buffer 中所有数据都被写入 channel。

// byte[] data = ...
ByteBuffer buffer = ByteBuffer.allocate(data.length);
buffer.put(data);
buffer.flip();
while (buffer.hasRemaining()) {
  channel.write(buffer);
}

 

其它方法:

  • write(ByteBuffer, long) 可以指定写入channel的位置,但不会改变 channel 当前位置。
  • write(ByteBuffer[]) 和 write(ByteBuffer[], int, int) 属于 GatheringByteChannel 的 数据聚集 特性。

 

关闭 FileChannel

可以直接调用 FileChannel.close() 方法关闭,也可以 try-with-resources 的方式关闭。

channel.close();

 

FileChannel 的 position

当读取 FileChannel 中的数据,或向其写入数据时,都会在 channel 的某个特定位置开始读取或写入。

如果不明确指定这个 位置,默认使用 channel 的 当前位置

可通过 position() 和 position(long) 获取与设置 channel 的 当前位置.

 

FileChannel 的 size

FileChannel.size() 方法返回的是 channel 所对应文件的大小(字节数)

 

裁剪 FileChannel

FileChannel.truncate(long) 方法可将 channel 中超出指定大小的数据丢弃。
如果指定的数据量大于等于当前 channel 的数据量,则原数据不会被改变。
如果指定的数据量小于 channel 的 position(当前位置),则 channel 的 position 会被更新为所指定数据量长度。

 

强制 FileChannel 数据落盘

出于性能方面的考虑,操作系统可能会先将 FileChannel 中的数据缓存在内存中,而不是直接写到磁盘。
可调用 FileChannel.force(boolean) 方法将那些尚未落盘的数据都写到磁盘。

  • force(true) 表示将文件内容和元信息都写入磁盘。
  • force(false) 表示只将文件内容写入磁盘,不包含元信息。

 

相关标签: nio