【Java NIO 简例】FileChannel
注:利用 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) 表示只将文件内容写入磁盘,不包含元信息。
上一篇: 介绍服务端 Netty 的工作架构图
下一篇: XML轻松学习手册(5)XML实例解析