一、概述
Channel是一个通道,可以通过它实现数据的读取和写入,它和之前讨论的输入、输出流有很大区别,通道与流的不同之处在于通道是双向的,流只是单向的,流区分输入流和输出流,一个流只能是输入流或者输出流,不能复用。通道解决了复用问题,它既可以处理输入数据,也可以处理输出数据,并且这两者可以同时进行,现在的底层操作系统都是全双工模式,可以支持读写同时操作。
channel封装了对数据源的操作,通过channel我们可以处理数据源,但是又不必关心数据源的具体物理结构。这个数据源可以是不同类型的,比如一个文件描述符、程序组件的打开连接或者是一个网络socket,在大多数应用中,数据源与channel是一一对应的,channel用于在字节缓冲区和数据源直接传输数据。
二、概念模型
channel是一个对象,可以通过它读写数据。NIO提供的channel和原IO提供的输入输出力比较,通道就像外观模式中的外观接口,由channel对外部数据源进行映射和包装,然后将数据交由buffer处理。channel自己并不进行数据处理,读取数据时,channel将数据源写入buffer,然后由buffer获取数据在进行其他操作;在写入数据时,也是先把数据源写入buffer中,然后再通过channel将数据写入目标位置。
NIO的通道类似流,但是跟流又不同,他们的区别如下:
1、通道既可以读取数据,也可以写入数据,流只是单向的;
2、通道支持异步读写,流只支持同步阻塞读写;
3、通道不能产生数据,也不会处理数据,都是通过buffer进行处理的;
通道的数据处理模型如下:
三、分类
channel的主要实现子类如下图所示:
这些channel主要分为几下部分:
1、文件操作相关的FileChannel;
2、UDP协议相关的DatagramChannel;
3、TCP协议相关的ServerSocketChannel、SocketChannel;
4、SCTP协议相关的SctpChannel、SctpMultiChannel、SctpServerChannel;
5、管道操作相关的SinkChannel、SourceChannel;
四、channel继承体系
SocketChannel继承体系如下图所示:
ServerSocketChannel继承体系如下图所示:
DatagramChannel继承体系如下图所示:
FileChannel继承体系如下图所示:
五、channel提供的API
与缓冲区不同,通道API主要由接口定义,不同操作系统上通道的实现会有很大差异,所以通道API仅仅描述接口可以做什么,但是具体如何实现,需要由操作系统提供。通道的实现一般由本地操作系统本地代码提供,这样我们就可以以一种受控并且可移植的方式来访问底层io服务。
通过之前的接口继承体系分析可知,不同通道的功能不尽相同,但是它们可提供的基础功能是类似的,因为它们继承了相同的接口,通用接口或抽象类有AutoCloseable、Closeable、Channel、InterruptibleChannel、AbstractInterruptibleChannel、SelectableChannel、AbstractSelectableChannel、NetworkChannel等。
1、通用接口提供的API
AutoCloseable 提供的接口如下: