Java NIO FileChannel是一个连接文件的Channel。通过file channel,可以从文件中读取数据,也可以写入数据到文件。Java NIO的FileChannel是Java 标准IO的替代方案。
FileChannel不能设置为非阻塞模式,它一直运行在阻塞模式。
Opening a FileChannel
在使用FileChannel之前需要先打开它。FileChannel不能直接打开它。获得FileChannel必须通过InputStream,OutputStrerm,RandomAccessFile。下面是一个通过RandomAccessFile打开FileChannel的例子。
RandomAccessFile file = new RandomAccessFile("data/nio.txt","rw");
FileChannel fileChannel = file.getChannel();
复制代码
Reading Data from a FileChannel
可以通过read()方法从FileChannel读取数据。下面是一个例子。
ByteBuffer buf = ByteBuffer.allocate(48);
int byteRead = inChannel.read(buf);
复制代码
首先,为一个Buffer分配空间,从FileChannel中读取的数据将放入到Buffer中。
然后,调用FileChannel的read方法。这个方法将FileChannel中的数据保存到Buffer中。read()方法的返回值表明向Buffer写入的字节数。如果返回-1,表明数据已经读完。
Writing Data to a FileChannel
向FileChannel中写入数据是通过FileChannel.write()方法来实现的,这个方法传递一个buffer参数。下面是一个例子。
String newData = "New String to write to a file..."+System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()){
channel.write(buf);
}
复制代码
注意FileChannel.write()是在while循环中调用的。因为无法保证write()方法一次能向FileChannel写入多少字节,因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节。
Closing a FileChannel
当FileChannel使用完之后需要关闭。下面是一个例子。
channel.close();
复制代码
FileChannel Position
在向FileChannel中读写数据时需要在一个指定的位置进行。可以通过FileChannel的position()方法来获得当前位置。
也可以通过FileChannel的position(long pos)方法来设置当前位置。
这里是两个例子。
long pos = channel.position();
channel.position(pos+123);
复制代码
如果将position设置在文件结束符之后,并且尝试从通道中读取数据,方法将会返回-1。文件结束标记。
如果将position设置在文件结束符之后,并且尝试从通道中写入数据,文件将撑大到当前位置,并且写入数据。这将导致文件空洞,磁盘上物理文件写入的数据间将会有空隙。
FileChannel Size
FileChannel的size()方法返回的是通道所连接的文件的大小。下面是一个例子。
long fileSize = channel.size();
复制代码
FileChannel Truncate
可以通过FileChannel的truncate方法截取一个文件。当截取一个文件时,文件在给定长度后面的内容都会被删除。例子如下:
channel.truncate(1024);
复制代码
这个例子将文件截断到1024个字节。
FileChannel Force
FileChannel的force()会强制将未写入到磁盘的数据保存到磁盘。操作系统出于性能考虑可能会缓存数据在内存中。所以并不能够保证写入到Channel中的数据真正写入到磁盘上,除非调用了force()方法。
force()方法有一个布尔值参数,表示文件的元数据是否也需要被刷新。
下面是一个同时刷新数据和元数据的一个例子。
channel.force(true);
复制代码