Java NIO FileChannel 是连接文件的channel。使用fileChannle可以实现从文件中读写数据。FileChannel是用来替代Java标准库IO API的。

FileChannel 不能被置为非阻塞模式,永远都是阻塞模式。

打开 FileChannle

在使用FileChannel之前,必须要先打开它。不能直接打开,需要通过InputStream\OutStream\RandomAccessFile来获得。举个例子:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();

从FileChannel读取数据

可以使用fileChannel提供的read()方法来读取,举个例子:

ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf)

首先,分配 Buffer,数据从FileChannle读取到Buffer中。
然后,调用FileChannel 的 read() 方法,这个方法实现了从FileChannel读取数据到Buffer中。read()方法返回的是写了多少个字节的数据到Buffer里。如果返回的是-1则表示文件中的数据已写完到buffer。

写数据到FileChannel

可以使用fileChannel提供的write()方法来写入,举个例子:

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);
}

注意,write() 方法在循环内被调用。此方法不会返回我们写了多少数据,所以需要循环写入直到写入完成。

关闭 FileChannel

当使用完后,必须执行关闭:

channel.close();

FileChannel Position

当读或写FileChannel时,实际上是在特定的Position。 也可以通过调用position()方法来指定一个position.

long pos channel.position();
channel.position(pos +123);

如果把position置为文件的末尾,然后尝试从channel中读取数据,就会拿到-1的结果。如果尝试写入数据,文件则会开始从此处写入数据。可能会导致漏洞。

FileChannel 大小

size()方法拿到大小:

long fileSize = channel.size();

FileChannel 截断

通过给定的长度来截断一个文件:

// 截断1024字节
channel.truncate(1024);

FileChannel Force

force()方法会把channel中不可写的数据刷新掉(flushes)。操作系统为了性能考虑会缓存数据,因此没有办法保证写入channel中的数据确实已经写入到磁盘中,调用force()方法来保证。传入参数true/false来确认是否要flushe :

channel.force(true);

参考

  1. Java NIO FileChannel