Java中IO和NIO的区别详细解析
作者:JackieZhengChina
1.IO和NIO的区别
NIO就是New IO在JDK1.4中引入。
IO和NIO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO快不少。
在Java API中提供了两套NIO,一套针对标准输入输出NIO,另一套就是网络编程IO。
IO | NIO |
面向流 | 面向缓冲 |
阻塞IO | 非阻塞IO |
无 | 选择器 |
面向流和面向缓冲区
- Java IO 是面向流的而Java NIO是面向缓冲区的,就如同一个的重点在于过程,另一重点在于一个有一个阶段。
在Java IO中读取数据和写入数据是面向流(Stream)的,就如同河流一样。所有的数据不停地向前的流淌,我们只能触碰到当前的流水。
如果需要获取某个数据的前一项或后一项数据那就必须自己缓存数据(将水从河流中打出来),而不能直接从流中获取(因为面向流就意味着我们只有一个数据流的切面)
- Java NIO中数据的读写是面向缓冲区(Buffer)的,读取时可以将整块的数据读取到缓冲区中,在写入时则可以将整个缓冲区中的数据一起写入。
这就好像是在河流上建立水坝,面向流的数据读写只提供了一个数据流切面,而面向缓冲区的IO则使我们能够看到所有的水(数据的上下文),也就是说在缓冲区中获取某项数据的前一项数据或者是后一项数据十分方便。这种便利是有代价的,因为我们必须管理好缓冲区,这包括不能让新的数据覆盖了缓冲区中还没有被处理的有用数据;将缓冲区中的数据正确的分块,分清哪些被处理过哪些还没有等等。
阻塞和非阻塞
- Java IO是阻塞的,如果在一次读写数据调用时数据还没有准备好,或者目前不可写,那么读写操作就会被阻塞直到数据准备好或目标可写为止。
- Java NIO则是非阻塞的,每一次数据读写调用都会立即返回,并将目前可读(或可写)的内容写入缓冲区或者从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作。
举个例子:
IO和NIO去超市买东西,如果超市中没有需要的商品或者数量还不够, IO会一直等到超市中需要的商品数量足够了就将所有需要的商品带回来。Java NIO则不同,不论超市中有多少需要的商品,它都将有需要的商品,立即全部买下并返回,甚至是没有需要的商品也会立即返回。
IO 要求一次完成任务,NIO允许多次完成任务
2.IO和NIO的适用场景
NIO是为弥补传统IO的不足而诞生的,但是NIO也有缺陷,应为NIO是面向缓冲区的操作,每一次的数据处理都是对缓冲区进行的,那就必须注意:在数据处理之前必须要判断缓冲区的数据是否完整或者已经读取完毕。如果没有,假设数据只读取了一部分,那么对不完整的数据处理没有任何意义。所以每次数据处理之前都要检测缓冲区。
注意:每次要进行数据处理必须保证数据已经准备完毕,但数据处理可以有多次。
IO和NIO各自使用场景:
IO:少量的连接,这些连接每次都要发送大量的数据。
NIO:需要管理同时打开的成千上万个连接,而这些链接每次只发送少量的数据,例如聊天服务器
IO和NIO的工作流程
Java IO 工作流程
由于Java IO是阻塞的,所以当面对多个流的读写时需要多个线程处理。例如在网络IO中,Server端使用一个线程监听一个端口,一旦某个连接被accept,创建新的线程来处理新建立的连接。
其中 read/write 是阻塞的。
Java NIO 工作流程
Java NIO 提供 Selector 实现单个线程管理多个channel的功能。
其中select 调用可能是阻塞的,也可以是非阻塞的。但是read/write是非阻塞的!
到此这篇关于Java中IO和NIO的区别详细解析的文章就介绍到这了,更多相关IO和NIO的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!