所有的channel都不应该通过构造器来直接创建,而是通过传统节点的InputStream、OutputStream的getChannel( )
方法返回对应的Channel,不同的节点获得的Channel不一样。如FileInputStream、FileOutputStream的getChannel( )方法返回的是FileChannel
。
FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。
1.打开FileChannel
在使用FileChannel之前,必须先打开它。但是,我们无法直接打开一个FileChannel,需要通过使用一个InputStream
、OutputStream
或RandomAccessFile
来获取一个FileChannel实例。RandomAccessFile返回的FileChannel是只读
还是读写
,则取决于RandomAccessFile打开文件的模式。下面是通过RandomAccessFile打开FileChannel的示例:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
2. Channel中最常用的三类方法map()、read()、write()
map():将channel对应的部分或全部数据映射成ByteBuffer;
read():从channel中读,read()方法返回的int
值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾。
write():向channel中写,使用FileChannel.write()
方法向FileChannel写数据,该方法的参数是一个Buffer。
其中map( )将map的方法签名。
read( )和write的示例如下:
2.1 从FileChannel读取数据
调用多个read()方法之一从FileChannel中读取数据。如:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
首先,分配一个Buffer。从FileChannel中读取的数据将被读到Buffer中。
然后,调用FileChannel.read()方法。该方法将数据从FileChannel读取到Buffer中。read()方法返回的int值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾。
2.2 向FileChannel写数据
使用FileChannel.write()方法向FileChannel写数据,该方法的参数是一个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中已经没有尚未写入通道的字节。
参考:http://ifeve.com/file-channel/