Netty学习前置知识:NIO三大组件

一、前言

在上一篇文章中我们学习了几种IO模型,由于Netty是基于NIO实现的所以我们今天继续学习NIO的相关知识,今天的主题是NIO的三大组件:Selector、Buffer、Channel。

二、NIO三大组件

在这里插入图片描述

一个NIO Demo

在讲述NIO三大组件之前,让我们先看一个基于NIO的Demo

public class Test {

    public static void main(String[] args) throws Exception {
        FileInputStream inputStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\新建文本文档.txt");
        //获取一个channel
        FileChannel channel = inputStream.getChannel();
        //申请一块内存空间
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        while (true) {
            int b = channel.read(byteBuffer);
            if(b == -1){
                break;
            }
            //切换成读模式
            byteBuffer.flip();
            while(byteBuffer.hasRemaining()){
                byte bt = byteBuffer.get();
                System.out.println((char)bt);
            }
            //清空byte buff
            byteBuffer.clear();
        }

    }
}

案例中的代码非常简单,实现的功能也就是从Txt中读取所有的内容然后挨个输出到控制台,这里就体现了NIO是面向缓冲区这一特性。

NIO三大组件结构图

image.png

(原谅我画图画的有点丑)

1、Buffer

Buffer翻译成中文就是缓冲器,想必你一定听过这样一句话NIO是面向缓冲区的,怎么理解这句话呢,个人的理解是,在NIO中数据的通信都是基于Buffer来实现的。
image.png
从源码中我们可Buffer是一个抽象类,他有许多子类例如我们上面用到的ByteBuffer,这里我们就以ByteBuffer为例。
image.png 可以看到ByteBuffer中有一个byte类型的数组,这是一片连续的内存空间,在集合之前的代码中我们使用ByteBuffer byteBuffer = ByteBuffer.allocate(10);向操作系统申请一片大小为10个字节的连续内存空间用充当缓冲区。
再看这行代码 int b = channel.read(byteBuffer); 结合这上面的结构图其实也很好理解了,channel想要获取数据就要通过buffer。这也就是为什么说 NIO是面向缓冲区的
小结:

  • NIO中的Buffer是内存中一块连续的空间
  • NIO是面向缓冲区的

2、Channel

channel翻译成中文就是管道,可以看到Channel是一个接口,
image.png

A nexus for I/O operations.
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
A channel is either open or closed. A channel is open upon creation, and once closed it remains closed. Once a channel is closed, any attempt to invoke an I/O operation upon it will cause a ClosedChannelException to be thrown. Whether or not a channel is open may be tested by invoking its isOpen method.
Channels are, in general, intended to be safe for multithreaded access as described in the specifications of the interfaces and classes that extend and implement this interface.
译文:Channel关联IO操作的
通道表示与能够执行一个或多个不同I/O操作(例如读取或写入)的实体(例如硬件设备、文件、网络套接字或程序组件)的开放连接。
通道打开或关闭。通道在创建时打开,一旦关闭,它将保持关闭状态。一旦通道关闭,任何对其调用I/O操作的尝试都会引发ClosedChannelException。可以通过调用其isOpen方法来测试通道是否打开。
通常,通道对于多线程访问是安全的,如扩展和实现该接口的接口和类的规范中所述。

这里我们以demo中FileChannel为例,我们知道通常程序要读取数据和写数据需要分为两个流输入流和输出流,而FileChannel即提供了读又提供了写(这里我们不深究是如何读写的),所以可以理解channel是对IO的封装。
image.png
小结:简单的来说Channel就是对IO的封装,并且对IO进行了增强,一个Channel代表着一个连接。(具体的之后放到netty学习中讲解,毕竟实际工作中我们很少会直接使用JDK自带的NIO)

3、Selector

在上一篇文章中我们知道了NIO中的多路复用模式,这里要说的selector就是一个多路复用器。
image.png
从代码中看Selector是一个抽象类,其中有一个比较重要的属性SelectionKey(选择关键字),从结构图中我们知道一个selector连接着多个channel,那么不同的channel就会有不同的事件类型,比如 channel1刚建立连接,channel2已结开始读取数据。所以在SelectionKey中也有对应的4个事类型
image.png
OP_READ:对应Channel的读操作
OP_WRITER:对应Channel的写操作
OP_CONNECT:对应Channel的连接操作
OP_ACCEPT:用于支持选择器检测到相应的服务器套接字通道已准备好接受另一个连接,或者有一个挂起的错误。
Selector会一直不断轮训所有的Channel并且根据不同的事件类型进行不同的处理。

三、总结

至此我们已经对NIO的三大组件有了一个初步的认识,之后的文章会学习如何使用这些组件。希望对你有所帮助。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值