Java NIO 中的 FileChannel 是用于连接文件的通道(Channel)。通过 FileChannel 可以读、写文件的数据。Java NIO 的 FileChannel 是相对标准 Java IO API 的可选接口。
FileChannel 不可以设置为非阻塞模式,他只能在阻塞模式下运行。

阅读文章的过程中如果有任何疑问,欢迎添加笔者为好友,拉您进【七日书摘】微信交流群,一起交流技术,一起打造高质量的职场技术交流圈子,抱团取暖,共同进步。
七日书摘官方群.jpg

打开文件通道(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 概述

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)

Java基础知识面试题篇(2020年2月最新版)

更技术学习请进入七日书摘官方群: 七日书摘官方群

七日书摘官方群群聊二维码.png

参考资源:
https://blog.csdn.net/Andrew_Yuan/article/details/80215164
https://wiki.jikexueyuan.com/project/java-nio-zh/java-nio-filechannel.html