Java NIO 中的 FileChannel 是用于连接文件的通道(Channel)。通过 FileChannel 可以读、写文件的数据。Java NIO 的 FileChannel 是相对标准 Java IO API 的可选接口。
FileChannel 不可以设置为非阻塞模式,他只能在阻塞模式下运行。
阅读文章的过程中如果有任何疑问,欢迎添加笔者为好友,拉您进【七日书摘】微信交流群,一起交流技术,一起打造高质量的职场技术交流圈子,抱团取暖,共同进步。
打开文件通道(Opening a FileChannel)
在使用 FileChannel 前必须打开它,打开一个 FileChannel 需要通过输入/输出流或者RandomAccessFile,下面是通过RandomAccessFile打开 FileChannel 的案例:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
从文件通道内读取数据(Reading Data from a FileChannel)
可以通过 read() 方法读取 FileChannel 中的数据。示例如下:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
首先分配一个 Buffer。用于从 FileChannel 中读取数据到 Buffer 中。
然后就可以调用 FileChannel.read() 方法。此方法将数据从 FileChannel 读入到缓冲区(Buffer)。read() 方法返回的 int 告诉缓冲区中有多少字节。返回 -1 则表示已经读取到文件结尾了。
向文件通道写入数据(Writing Data to a FileChannel)
使用 FileChannel.write() 方法向 FileChannel 写入数据,该方法的参数是一个 Buffer,flip()是将position 移到开头。如:
String newData = "New String to write to file..." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()) {
channel.write(buf);
}
注意这里的 FileChannel.write() 调用写在了 wihle 循环中,这是因为无法保证 write() 单次写入 FileChannel 的字节数,因此需要循环写入直到缓冲区(Buffer)中没有尚未写入 FileChannel 中的更多数据为止。
关闭通道(Closing a FileChannel)
当你使用完 FileChannel 后必须将其关闭。关闭操作如下:
channel.close();
FileChannel 的 position 方法(FileChannel Position)
当操作 FileChannel 时读写都是基于某个特定起始位置的(position),可以通过 position() 方法获取 FileChannel 当前位置。
你也可以通过 position(long pos)方法 设置 FileChannel 的当前位置。
获取和设置 FileChannel 的示例如下:
long pos = channel.position(); // 获取位置
channel.position(pos +123); // 设置位置
假设我们把当前位置设置为文件结尾之后,那么当我们试图从通道中读取数据时就会发现返回值是-1,表示已经到达文件结尾了。
如果把当前位置设置为文件结尾之后,在想通道中写入数据,文件会自动扩展以便写入数据,但是这样会导致文件中出现类似空洞,即文件的一些位置是没有数据的。
FileChannel 的 size 方法(FileChannel Size)
FileChannel 实例的 size() 方法返回该实例所关联文件的大小。
long fileSize = channel.size();
FileChannel 的 truncate 方法(FileChannel Truncate)
可以使用 FileChannel.truncate() 方法截取指定长度的文件。截取文件时,文件中指定长度后面的部分将被删除。
看如下示例:
channel.truncate(1024);//将文件的长度截取为1024字节
FileChannel 的 force 方法(FileChannel Force)
FileChannel.force() 方法将通道(Channel)里尚未写入磁盘的数据强制写入磁盘。出于性能方面的考虑操作系统会将数据缓存在内存中,所以无法保证写入到FileChannel 里的数据一定会即时写到磁盘上。要保证这一点需要调用 force() 方法。
force() 方法有一个 boolean 类型的参数,指明是否同时将文件元数据(权限信息等)也一并强制写入磁盘。
下面是一个同时刷新数据和元数据的示例:
channel.force(true);
英文原文链接:http://tutorials.jenkov.com/java-nio/file-channel.html
------完------
推荐阅读:
Java NIO 简明教程 之 Java NIO Channel
Java NIO 简明教程 之 Java NIO 缓冲(Buffer)
Java NIO 简明教程 之 Java NIO Scatter/Gather
Java NIO 简明教程 之 Java NIO 通道之间的数据传输(Channel to Channel Transfers)
Java NIO 简明教程 之 Java NIO 选择器(Selector)
参考资源:
https://blog.csdn.net/Andrew_Yuan/article/details/80215164
https://wiki.jikexueyuan.com/project/java-nio-zh/java-nio-filechannel.html