最后更新时间:2014-06-25
一个Java NIO FileChannel是一个连接到文件的通道。使用一个文件通道你可以从一个文件中读取数据,以及写数据到文件中。这个Java NIO FileChannel类同标准的Java IO API是一个可供选择的读文件操作。
一个FileChannel不能设置为非堵塞模式。它总是运行在堵塞模式下。
打开一个FileChannel
在你使用一个FileChannel之前,你必须打开它。你不能直接打开一个FileChannel。你需要通过一个InputStream,OutputStream,或者一个RandomAccessFile去获取一个FileChannel。这里有一个通过一个RandomAccessFile如何去打开一个FileChannel:
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被分配了。这个数据从FileChannel中读到Buffer中。
第二步这个FileChannel.read()方法被调用了。这个方法读取来自FileChannel中的数据进入Buffer。通过read方法返回的int值告诉你有多少个字节写进了Buffer中。如果返回的值是-1,那就达到了文件的结尾了。
写数据进入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循环中是怎么被调用的。这个write方法不会保证有多少字节会写入到FileChannel。因此我们会重复write方法的调用直到这个buffer中没有更多的字节可写了。
关闭一个FileChannel
当你使用一个FileChannel多一些事情的时候,你必须关闭它。这里有一个实例怎么做他:
channel.close();
当你在指定的位置读或者写一个FileChannel的时候。你可以通过调用position方法获取FileChannel对象的当前位置。
你也可以通过调用position(long pos)方法设置FileChannel的位置。
这里有两个例子:
long pos channel.position(); channel.position(pos +123);
如果你在文件的结尾设置了这个位置,并且写数据到FileChannel,这个文件将会被扩充适应这个位置去写数据。这个可能发生在一个“文件洞”里面,在写数据中磁盘上的物理文件有一个缺口的地方。
FileChannel大小
FileChannel对象的size方法返回了这个通道连接到的那个文件的文件大小。这里有一个简单的例子:
long fileSize = channel.size();
你可以通过调用FileChannel.truncate()方法截取一个文件。当你截取一个文件的时候,在给予的长度的地方截取他(将会丢弃掉这个文件新结束的字节,即从这个长度到最后的字节会丢弃掉)。这里有一个简单的例子:
channel.truncate(1024);
这个例子是在1024个字节处截取这个文件。
FileChannel Force
这个FileChannel.force()方法会把来自channel中所有未写的数据写到磁盘中去。一个操作系统可能因为性能的原因会缓存数据到内存中,以至于你不能保证写到channel中的数据确定的写到磁盘中了,知道你调用force()方法。
这个force()方法有一个boolean类型的作为参数,告诉这个文件的元数据(权限等等)是否也应该被写入。
这里有一个既会写数据也会写元数据到磁盘的例子:
channel.force(true);