您当前的位置: 首页 >  nio

恐龙弟旺仔

暂无认证

  • 0浏览

    0关注

    282博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

NIO源码解析-Channel简介

恐龙弟旺仔 发布时间:2021-09-08 12:03:51 ,浏览量:0

前言:
        Buffer、Channel、Selector,NIO三大件。之前的博客中我们介绍了Buffer的一系列知识。从本篇开始,笔者将会介绍下Channel相关的知识。
1.Channel基本定义
        Channel,翻译过来就是通道。通道表示打开到IO设备(文件、套接字)的连接。
        通道有点类似于流的概念,就是InputStream和OutputStream,都是可以用来传输数据的。但是两者之间又有本质的不同,不同点如下:
        * 通过通道,程序既可以读数据又可以写数据;流的读写则是单向的(比如InputStream就是读,OutputStream就是写)
        * 通道可以进行数据的异步读写;而流的读写一般都是阻塞的同步的;
        * 通道的数据读写需要通过Buffer,Buffer的操作比较灵活;而流的话直接读写在byte[]中;
2.Channel的类图
        我们从几个层级来展示下Channel由上至下的接口实现

2.1 Channel接口
public interface Channel extends Closeable {
    // 当前通道是否打开
    public boolean isOpen();
    // 关闭通道
    public void close() throws IOException;
}
        一个打开的通道即代表是一个特定的IO服务的特定连接。
        当通道关闭后,该连接会丢失。对于已经关闭的通道进行读写操作都会抛出ClosedChannelException。
        调用close方法来关闭通道时,可能会导致通道在关闭底层的IO服务的过程中线程暂时阻塞。通道关闭的阻塞行为取决于操作系统或对应文件系统。
2.2 InterruptibleChannel
        只是一个标记接口,表示当前通道是可被中断的。
        实现该接口的通道有以下特性:如果一个线程在一个通道上被阻塞并且同时被中断,那么当前通道则会被关闭,同时该阻塞线程也会产生一个ClosedByInterruptException。
2.3 ReadableByteChannel和WritableByteChannel
// WritableByteChannel.java
public interface WritableByteChannel extends Channel {
	public int write(ByteBuffer src) throws IOException;
}

// ReadableByteChannel.java
public interface ReadableByteChannel extends Channel {
    public int read(ByteBuffer dst) throws IOException;
}

可以看到,这两个就是新增了对ByteBuffer的read和write操作

2.4 ByteChannel
public interface ByteChannel
    extends ReadableByteChannel, WritableByteChannel
{
}

只实现其中一个接口(ReadableByteChannel或WritableByteChannel)则只能实现单向的读或写,数据只能在一个方向上传输。

ByteChannel继承了ReadableByteChannel和WritableByteChannel,

实现ByteChannel的类可以同时进行读和写,实现数据的双向传输。

2.5 SelectableChannel及其实现类
/** A channel that can be multiplexed via a {@link Selector}. */
public abstract class SelectableChannel
    extends AbstractInterruptibleChannel
    implements Channel
{
	public abstract SelectorProvider provider();
    public abstract SelectionKey keyFor(Selector sel);
    public abstract SelectionKey register(Selector sel, int ops, Object att)
        throws ClosedChannelException;
    ...
}
可以看到,SelectableChannel不再是单打独斗的Channel了,而是与Selector进行了结合。
从它的注释中我们能看到,这种Channel是一种通过Selector进行多路复用的Channel。
看其的实现类SocketChannel、ServerSocketChannel,我们也知道,这些都是使用多路复用的最佳场景。
2.6 FileChannel
/** A channel for reading, writing, mapping, and manipulating a file. */
public abstract class FileChannel
    extends AbstractInterruptibleChannel
    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
{
	...
}
        FileChannel看其注释,就会了解到,这是一个操作文件的Channel。我们通过FileChannel可以读、写、mapping(映射)、操作一个文件。
总结:
        从最终实现上来看,我们可以将IO简单分为两大类:File IO和Socket Stream IO,分别用于操作文件和网络套接字。
        后续的文章中,我们也按照这个大方向,先介绍File IO相关操作,后续再介绍Socket Stream IO相关操作。

关注
打赏
1655041699
查看更多评论
立即登录/注册

微信扫码登录

0.0624s