1 Channel
– 数据的源头或者数据的目的地
![]() 2.1 基本接口
基础的通道接口只有两个方法,判断通道是否开启,以及关闭通道 2.2 读和写
ReadableByteChannel和WritableByteChannel定义了通道基本都是基于ByteBuffer操作的 ByteChannel继承了前面两个,因此一般可以被用来实现可读可写的通道 public interface ByteChannel extends ReadableByteChannel, WritableByteChannel { } 2.3 阻塞与非阻塞SelectableChannel表明了通道是支持有条件的选择,即Selector,和非阻塞结合就可以实现多路复用的 通道可以以阻塞(blocking)或非阻塞(nonblocking )模式运行。非阻塞模式的通道永远不会让调用的线程休眠。请求的操作要么立即完成,要么返回一个结果表明未进行任何操作。只有面向流的(stream -oriented)的通道,如 sockets 和pipes才能使用非阻塞模式,将非阻塞 2.4 可中断与不可中断如果一个通道实现了Interrupted接口,那么,当他被阻塞,并且发生中断的时候,那么该通道将会被中断,线程会抛出一个ClosedByInterruptException异常,如果一个线程的状态是中断,他试图访问一个通道,那么通道将立即被关闭 2.5 Scatter和Gather简单的说就是可以将读取的数据填充到对个缓冲区,将多个缓冲区的数据一次写出,号称和Direct内存结合性能会很不错,还没能力考证... 1.对于写入,一般的框架在,都是在写完一段数据,就给一个事件,表明写完,这种场景下Gather的作用就不大了,不过如果能够接受批量写的话(比如每次写10段数据,写完以后一段段通知),那也许可以试试 2.对于读取,感觉作用不是很大,把head和body分到两个ByteBuffer里和一个ByteBuffer里有毛区别? 参考 NIO - Scatter/Gather 2.6 打开通道(文件/Socket)
从广义IO角度来说,有两大类:File IO和Stream IO,因此通道也大致有两类,FileChannel和套接字(Socket)通道,包括SocketChannel、ServerSocketChannel和DatagramChannel,Socket通过可以直接通过工厂方法创建,但是一个FileChannel只能通过一个打开的RandomAccessFile、FileInputStream、FileOutputStream对象上调用getChannel方法来获取 SocketChannel sc = SocketChannel.open( );
DatagramChannel dc = DatagramChannel.open( ); RandomAccessFile raf = new RandomAccessFile ("somefile", "r"); FileChannel fc = raf.getChannel( ); 2.7 使用通道(特性和IO实例相关)
通道可以使单向的或者双向的,即只读/只写/可读可写 对于每个File或者Scoket通道来说,都是双向的,对于Socket不是我关心,因为它本身就是双向的,但是对于File,可以在不同的时候以不同的权限打开,因此Read-only打开的文件调用write方法时候会抛出NonWriteChannelException,通道会连接一个通道实例(channel instance),具体的属性受该实例的限制,比如文件没有写权限,但是可能有write方法。 |
|
来自: 碧海山城 > 《通道和NIO基础》