#08.Java NIO FileChannel
FileChannel是一个用于连接文件的通道类。使用FileChannel你可以读取文件的数据或往文件里写入数据。使用FileChannel可以代替标准的Java IO API中对文件的操作。
FileChannel不能设置为非阻塞模式,它总是以阻塞模式运行。
##打开FileChannel(Opening a FileChannel)
当需要使用FileChannel时,你需要首先打开一个FileChannel,但你不能直接打开。你必须要通过InputStream,OutputStream或RandomAccessFile来获得一个FileChannel实例。如下面这个例子:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();##从FileChannel中读取数据(Reading Data from a FileChannel)
从FileChannel中读取数据,可以调用多个重载的read()方法。
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);当**缓冲区(Buffer)**分配之后,数据从FileChannel中读取到缓冲区。
当FileChannel.read()被调用后,这个方法会从FileChannel中读取数据到缓冲区。read()方法会返回一个int值,这个值代表了写入缓冲区的字节数。如果返回值是-1,则没有数据被读取。
##往FileChannel中写入数据(Writing Data to a FileChannel)
往FileChannel中写数据用的是FileChannel.write()方法,这个方法也会带有个Buffer类型参数。
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()方法是在while循环里面进行的。我们并不知道有多少数据要写入到FileChannel中,因此我们需要重复地调用write()方法直到缓冲区中没有数据可写。
##关闭FileChannel(Closing a FileChannel)
当使用完FileChannel后,必须要关闭它:
channel.close(); ##FileChannel Position
当从FileChannel读取数据往其中写人数据时,我们需要要指定特定的位置。你可以通过调用position()方法来获得FileChannel当前的位置。
你也可以通过position(long pos)方法来设置FileChannel的位置。
long pos channel.position();
channel.position(pos +123);如果你将position设置到文件的末尾之后,当你再对FileChannel进行读取时,将会返回-1,表明读取到了文件末尾。
如果你将position设置到文件的末尾之后,让你往FileChannel写入数据时,文件就会自动拓展到position所指定的位置并写入数据。这会导致文件空洞(File Hole)。
##FileChannel Size
FileChannel.size()方法会返回通道所连接的文件的大小。
long fileSize = channel.size(); ##FileChannel Truncate
你可以通过FileChannel.truncate()方法对通道所关联的文件进行截取:
channel.truncate(1024);##FileChannel Force
FileChannel.force()方法会将所有通道中的数据刷新到磁盘中。操作系统会处于性能考虑将数据缓存到内存中,所以你不能保证写入到通道中的数据会立刻同步到磁盘,因此你可以通过force()方法将通道中的数据刷新到物理磁盘。
FileChannel.forece()方法带有一个布尔类型的参数,这个参数用于指定文件的**元数据(meta data)**是否也需要刷新到物理磁盘。
channel.force(true);