(三)nio通道之Channel的类型、通道的创建和通道的Scatter(分散)和Gather(聚集)

一、通道的分类:

通道(Channel)是访问I/O服务的导管。I/O广义上可分为两大类:File I/O和Stream I/O。相应的会有两大类型的通道,它们分别是文件(file)通道和套接字(socket)通道。

主要的文件通道有:

    FileChannel:用于读取、写入、映射和操作文件的通道。

主要的套接字通道有:

    SocketChannel:通过 TCP 读写网络中的数据。

    ServerSocketChannel :可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。

    DatagramChannel:通过 UDP 读写网络中的数据通道。

其中前两个为TCP的套接字通道,后一个为UDP套接字通道。

-------------------------------------------------------------------------

二、通道的创建:

通道可以以多种方式创建。Socket 通道有可以直接创建新 socket 通道的工厂方法。但是一个FileChannel 对象却只能通过在一个打开的 RandomAccessFile、FileInputStream 或 FileOutputStream对象上调用 getChannel( )方法来获取。不能直接创建一个 FileChannel 对象。

如:

    SocketChannel sc = SocketChannel.open( );

    DatagramChannel dc = DatagramChannel.open( );

    FileChannel fc = RandomAccessFile raf = new RandomAccessFile ("somefile", "r").getChannel( );

    FileChannel fc = new FileInputStream(path).getChannel();

在java.net 的 socket 类也有新的 getChannel( )方法。这些方法虽然能返回一个相应的 socket 通道对象,但它们却并非新通道的来源。

----------------------------------------------------------------------

三、使用通道:


通道可以是单向的,也可以是双向的。一个channel类可以实现ReadableByteChannel接口定义read()方法,而另一个channel类也可以实现WritableByteChannel接口定义的write()方法。实现这两个接口其中之一的类都是单向的,只能在一个方向上进行传输数据。如果一个类同时实现了这两个接口,那么它是双向的,可以双向进行传输数据。如上图所示:ByteChannel是一个实现了WritableByteChannel和ReadableByteChannel的接口,该ByteChannel的实现类可以进行双向传输数据。

实例:

public class ChannelCopy {
public static void main(String[] args) throws Exception {
ReadableByteChannel src = Channels.newChannel(System.in);
WritableByteChannel dest = Channels.newChannel(System.out);
channelCopy1(src, dest);
src.close();
dest.close();
}
private static void channelCopy1(ReadableByteChannel src, WritableByteChannel dest) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(16 * 1024);
while ((src.read(buffer)) != -1) {
buffer.flip();
dest.write(buffer);
buffer.compact();
}
buffer.flip();
while (buffer.hasRemaining()) {
dest.write(buffer);
}
}

}

-------------------------------------------------------------

四、Scatter(分散)和Gather(聚集):

Scatter(分散)和Gather(聚集)是指在多个缓冲区中实现一个简单的I/O操作。

对于一个write操作而言,数据是从几个缓冲区按顺序抽取(成为gatter)并沿着通道发送的。缓冲
区本身并不需要具备这种 gather 的能力(通常它们也没有此能力)。该 gather 过程的效果就好比全

部缓冲区的内容被连结起来,并在发送数据前存放到一个大的缓冲区中。


对于 read 操作而言,从通道读取的数据会按顺序被散布(称为 scatter)到多个缓冲区,将每个缓冲区填满直至通道中的数据或者缓冲区的最大空间被消耗完。


1、分散读取(Scattering Reads):是指从 Channel 中读取的数据“分散”到多个 Buffer 中。

注意:按照缓冲区的顺序,从 Channel 中读取的数据依次将 Buffer 填满。


2、聚集写入(Gathering Writes)是指将多个 Buffer 中的数据“聚集”到 Channel。

注意:按照缓冲区的顺序,写入 position 和 limit 之间的数据到 Channel 。


3、将数据从源通道传输他 到其他  Channel  中 :


4、将数据从源通道传输他 到其他  Channel  中:












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值