在NIO的实现中,Buffer是一个抽象类。JDK为每一种Java原生类型都创建了一个Buffer,如图所示。
除了ByteBuffer外,其他每一种Buffer都具有完全一样的操作,唯一的区别仅仅在于它们所对应的数据类型。因为ByteBuffer多用于绝大多数标准I/O操作的接口,因此它有些特殊的方法。
在NIO中和Buffer配合使用的还有Channel。Channel是一个双向通道,既可读,也可写。有点类似Stream,但Stream是单向的。应用程序中不能直接对Channel进行读写操作,而必须通过Buffer来进行。比如,在读一个Channel的时候,需要先将数据读入到相对应的Buffer,然后再Buffer中进行读取。
以一个简单的读文件为例,在读取文件时,首先将文件打开,并取得文件的Channel:
FileInputStream fin = new FileInputStream(new File(“d:\\temp_buffer.tmp”));
FileChannel fc=fin.getChannel();
要从文件Channel中读取数据,必须使用Buffer。因此:
ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
fc.read(byteBuffer);
此时,文件内容已经存在byteBuffer中,因此可以关闭通道,并准备读取byteBuffer:
fc.close();
byteBuffer.flip();
之后,就可以从byteBuffer中取得文件内容。
一个使用NIO进行文件复制的例子如下,它展示了通过NIO进行文件读取和文件写入操作。
public static void nioCopyFile(String resource, String destination)
throws IOException {
FileInputStream fis = new FileInputStream(resource);
FileOutputStream fos = new FileOutputStream(destination);
FileChannel readChannel = fis.getChannel(); //读文件通道
FileChannel writeChannel = fos.getChannel(); //写文件通道
ByteBuffer buffer = ByteBuffer.allocate(1024); //读入数据缓存
while (true) {
buffer.clear();
int len = readChannel.read(buffer); //读入数据
if (len == -1) {
break; //读取完毕
}
buffer.flip();
writeChannel.write(buffer); //写入文件
}
readChannel.close();
writeChannel.close();
}
选自 uucode.net