今天再次看一遍NIO的通道。好好梳理下思路
我以最简单Demo为例,简单说明NIO的使用方式。不探讨具体的细节,因为一次性吸收这么多知识确实有些吃力。
简单的Demo需要你掌握这些内容:
1、开启一个通道。
FileChannel对象可以通过一个打开的RandomAaccessFile、FileInputStream、FileOutputStream的getChannnel方法得到。
注*:Socket通道可以用过SocketChannel、ServerSocketChannel、DatagramChannel的工厂方法创建(open()方法)
使用Channels的静态方法newChannel也可以产生通道。
2、通道是分读写方向的
ReadableByteChannel是读通道、WritableByteChannel是读通道、ByteChannel是读写通道
注*:通道不能改变权限,例如FileInputStream获得的是文件的读权限,那个使用getChannel获得的通道也是只读的,调用其他权限会抛出异常。
3、ByteChannel的read和write方法均使用ByteBuffer对象作为参数。如果还能读取或输入内容,则均返回读取/输入的字节数。
Demo:
public static void main(String[] args) {
FileInputStream filein = null;
FileOutputStream fileout = null;
FileChannel fileChannel = null;
FileChannel outChannel = null;
try {
filein = new FileInputStream(new File("D:\\test.txt"));
fileout = new FileOutputStream(new File("D:\\testcp.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
fileChannel = filein.getChannel();
outChannel = fileout.getChannel();
ByteBuffer fileBuffer = ByteBuffer.allocateDirect(1024);
try {
while((fileChannel.read(fileBuffer)) != -1){
System.out.println(fileBuffer.toString());
fileBuffer.flip();
outChannel.write(fileBuffer);
fileBuffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(filein != null){
fileChannel.close();
filein.close();
}
if(fileout != null){
outChannel.close();
fileout.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
通道的使用还有一点很关键的知识需要掌握,就是BufferByte的读写过程、position/limit/capacity三个标记的运用。这一点的知识可以参考我的另外一个博客,javaNIO学习笔记之缓冲区。其实通道处理文件时也有position属性,此处暂不仔细研究。
*注:通道有阻塞和非阻塞模式,但是只有面向流(socket/pipes)的通道才能使用非阻塞模式。
可以使用close方法关闭一个通道。当一个通道被阻塞时,也可以使用interrupt方法来关闭一个实现了InterruptibleChannel接口的通道