栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Java基础】IO流

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Java基础】IO流

文章目录
  • 一、IO是什么
  • 二、IO流的分类
  • 三、字节流和字符流的区别:
  • 四、BIO,NIO,AIO 有什么区别
  • 五、什么是IO多路复用
  • 六、NIO监听socket数量有没有限制
  • 七、select/poll/epoll之间的区别
  • 八、epoll 水平触发(LT)与 边缘触发(ET)的区别


一、IO是什么

Linux 系统中一切皆文件,而文件指的就是一些二进制的流,我们在做进程间通信时,都是对这些流进行操作,简称 IO 操作。在操作系统的层面,这些操作都是通过文件描述符来进行操作的。

通常用户进程的一个完整 IO 分为两个阶段:从用户空间到内核空间,从内核空间到设备空间。

  • 内核空间:存放的是内核代码和数据
  • 用户空间:存放的是用户程序代码和数据

以输入操作为例,用户进程进行了IO操作后,内核会先看缓冲区有没有数据,如果没有,则从设备空间读取,因为设备IO是比较慢的,所以会存在一个等待的过程。

所以 IO 操作的流程大致分为两步,等待 IO 操作就绪、数据拷贝
IO 一般有三种,内存 IO 、网络 IO、磁盘 IO。

二、IO流的分类

Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。

  • InputStream/OutputStream: 字节数入流、字节输出流。
  • Reader/Writer: 字符输入流、字符输出流。
三、字节流和字符流的区别:
  • 字节流默认不使用缓冲区;字符流使用缓冲区
  • 编码不同:
    1、字节流的处理:采用ASCII编码,主要用在处理二进制数据,它是按字节来处理的但实际中很多的数据是文本。
    2、字符流的处理:采用Unicode编码,按虚拟机的encode来处理,也就是要进行字符集的转化。
四、BIO,NIO,AIO 有什么区别

要理解三者区别,主要从同步/异步、阻塞/非阻塞 两个维度来理解:

  • 同步:java自己去处理io。

  • 异步:java将io交给操作系统去处理,告诉缓存区大小,处理完成回调

  • 阻塞:使用阻塞IO时,Java调用会一直阻塞到读写完成才返回。

  • 非阻塞:使用非阻塞IO时,如果不能立马读写,Java调用会马上返回,当IO事件分发器通知可读写时在进行读写,不断循环直到读写完成。

BIO:Block IO 同步阻塞IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
NIO:Non IO 同步非阻塞IO ,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了IO多路复用,但IO操作还是同步操作。
AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞IO ,异步 IO 的操作基于事件和回调机制。

以socket.read()为例子:

  • 传统的BIO,如果TCP RecvBuffer里没有数据,函数会一直阻塞,直到收到数据,返回读到的数据。
  • 对于NIO,如果TCP RecvBuffer有数据,就把数据从网卡读到内存,并且返回给用户;反之则直接返回0,永远不会阻塞。
  • 最新的AIO(Async I/O)里面会更进一步:不但等待就绪是非阻塞的,就连数据从网卡到内存的过程也是异步的。
  • 换句话说,BIO里用户最关心“我要读”,NIO里用户最关心"我可以读了",在AIO模型里用户更需要关注的是“读完了”。
五、什么是IO多路复用

IO多路复用是一种同步非阻塞 IO 模型,实现一个线程可以监视多个文件句柄,一旦某个文件句柄就绪,就能通知应用程序进行相应的读写操作,没有文件句柄就绪时会阻塞应用程序,交出 CPU。多路指的是网络连接,复用指的是同一个线程。

在Java代码层面,NIO包提供了一个选择器selector,我们把需要检查的Socket连接注册到这个selector中,然后主线程会阻塞在Selector#select方法里,当选择器发现某个socket就绪了,就会唤醒主线程。然后我们可以通过selector获取到就绪状态的socket进行相应的处理。

六、NIO监听socket数量有没有限制
  • select 使用的是bitmap表示需要检查的socket集合,因此有1024的限制。
  • poll 使用数组就没有这个限制了,它就可以让咱们线程监听超过1024个socket限制
七、select/poll/epoll之间的区别

select缺点:

  • 单个进程所打开的FD是有限制的,通过FD_SETSIZE设置,默认1024(32位机默认是1024个。64位机默认是2048)
  • 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
  • 对socket扫描时是线性扫描,采用轮询的方法,效率较低(高并发时)

poll 缺点:与select相比,使用了数组,因此没有fd的限制,其它基本一样。

epoll 在poll方法上,针对文件句柄操作进行了改进。

  • 做到了输入输出参数分离,只需要一次将文件描述符拷贝到内存中,减少拷贝过程,不像 select 每次循环都要传入需监听的fd列表。
  • 在内核空间创建了epoll_event的结构,划分了两块区域,存放需要监听的fd列表和就绪列表,存放就绪状态的socket信息。
  • epoll 使用事件回调机制,epoll_wait 会直接访问就绪队列就知道哪些文件描述符就绪了,不需要像 select、poll 使用轮询方式再次进行遍历。
  • 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

    Redis和Nginx使用的IO多路复用技术,就是epoll。
八、epoll 水平触发(LT)与 边缘触发(ET)的区别

多路I/O复用不管是select,poll还是epoll,其都是通过同时监听多个文件描述符,当有文件文件描述符处于就绪状态时,触发通知

LT(Level Trigger,水平触发)模式和ET(Edge Trigger,边沿触发)模式是两种文件描述符准备就绪的通知模式

LT模式 水平触发通知:只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作。
ET模式 边沿触发通知:如果文件描述符自上次状态检查以来有了新的I/O活动(比如新的输入),此时才会触发通知。

  • ET 的性能比 LT 性能更高,因为 epoll_wait 返回的次数少了很多。但同时,ET需要一次完成所有数据的读取,因为下次读取时,不会再返回了。

  • select和poll只支持LT工作模式,epoll的默认的工作模式是LT模式。

Nginx 默认采用 ET 触发来使用epoll。Redis使用的是LT触发
Netty 也使用的IO多路复用,待研究

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851997.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号