跳到主要内容

前言

Java IO 是Java 用于操作文件的一个包,它的核心是对于字节、字符的输入输出

IO流的本质是数据传输,并且流也是单方向的,IO流主要分为两类:字节流和字符流

字节流可以处理任何类型的数据,而字符流只能处理字符类型的数据

Unix IO 模型

在说Java IO之前我先说一下Unix IO ,Unix IO有五种模型,分别是阻塞IO,非阻塞IO,IO多路复用,信号驱动IO,异步IO

阻塞IO

阻塞IO是最基本的IO模型,应用进程监听端口后就一直处于阻塞状态,直到数据准备好之后才会唤醒。

我们需要知道在该进程在被阻塞的时候,其他进程仍然能继续执行,这样不会消耗CPU时间,这样执行效率也会高一些

image.png

非阻塞IO

非阻塞IO发起系统调用之后,会判断数据是否准备好,如果准备好就进行拷贝,如果没有准备好就进行重试,这样会导致CPU大量时间花费在系统调用上

image.png

IO多路复用

使用select或者poll等待数据,并且可以等待返回,这一过程会被阻塞,当返回可以开始拷贝的时候,再次发起recvfrom将数据拷贝 image.png

信号驱动IO

相较于IO多路复用,这种方式在等待数据的时候是非阻塞的,应用程序在发送SIGIO信号之后,会发起recvfrom系统调用然后拷贝数据等

image.png

异步IO

在应用程序发起IO操作之后,系统会直接返回,如果此时有数据就绪,那么就会直接去拷贝数据,拷贝完成就去处理,如果此时没有数据,就会等待数据就绪,不同的是,整个过程,进程不会阻塞

image.png

Java IO

关于Java IO,我们常见的三种模型,分别是BIO,NIO,AIO

BIO

BIO全称为:Blocking IO,直译为阻塞IO,所以对于BIO模型,我们可以类比为Unix的阻塞IO模型,例如我们在进行socket通信的时候,客户端会向服务端发送请求,而对于BIO模型,客户端发出请求之后什么都不会做,会一直进行等待,等待服务端返回或者网络出现问题

NIO

NIO全称为:New IO ,直译为新的IO,他是JDK1.4引入的新的IO方式,同样的NIO提供了不同于普通IO的工作方式,对NIO他有三个核心,分别是通道(channel),缓冲区(buffer),选择器(selector)。

  • 通道

通道其实就是对于Java对于IO流的一个模拟,我们知道流是单向的,而对于通道来说,他是双向的,既可以用作读,也可以用作写,也可以同时作用读写

  • 缓冲区

对于缓冲区,其实我觉得缓冲区与通道是不可分割的一部分,我们的数据在给一个通道用于发送的时候,必须要经过缓冲区,同样的通道读取数据的时候也必须经过缓冲区

  • 选择器

Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来选择通道,这些通道里已经有可以处理的输入,或者选择已准备写入的通道,这种选择器机制,使得一个单独的线程很容易来管理多个通道。

对于NIO他与普通的IO最大的不同就是他是面向缓冲区的,而普通IO是面向流的。

普通IO读取的时候,流传送多少就读多少,并且前后移动流中的数据

NIO读取的时候,是把数据加载到缓冲区中,如果需要我们可以在缓冲区中前后移动

AIO

AIO全称为:Asynchronous IO,直译为异步IO,前面我们说的NIO和BIO都是基于同步的,而AIO是异步的,对于AIO来说,最大的一个特性就是异步,我们可以类比Unix的异步IO,我们的进程不会被阻塞,而异步IO是基于操作系统的,我们在发起调用之后,不用管内核IO返回结果,当操作系统内核处理完成之后的时候让操作系统告诉进程。

其实可以想象成老师批改作业,老师先把所有同学的作业都收上来,然后改完一个去叫这个同学,让他修改自己的错误