Java中IO和NIO的区别详细解析

 更新时间:2023年11月22日 08:43:04   作者:JackieZhengChina  
这篇文章主要介绍了Java中IO和NIO的区别详细解析,IO和NIO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO快不少,需要的朋友可以参考下

1.IO和NIO的区别

NIO就是New IO在JDK1.4中引入。

IO和NIO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO快不少。

在Java API中提供了两套NIO,一套针对标准输入输出NIO,另一套就是网络编程IO。

IONIO
面向流面向缓冲
阻塞IO非阻塞IO
选择器

面向流和面向缓冲区

  • Java IO 是面向流的而Java NIO是面向缓冲区的,就如同一个的重点在于过程,另一重点在于一个有一个阶段。

在Java IO中读取数据和写入数据是面向流(Stream)的,就如同河流一样。所有的数据不停地向前的流淌,我们只能触碰到当前的流水。

如果需要获取某个数据的前一项或后一项数据那就必须自己缓存数据(将水从河流中打出来),而不能直接从流中获取(因为面向流就意味着我们只有一个数据流的切面)

  • Java NIO中数据的读写是面向缓冲区(Buffer)的,读取时可以将整块的数据读取到缓冲区中,在写入时则可以将整个缓冲区中的数据一起写入。

这就好像是在河流上建立水坝,面向流的数据读写只提供了一个数据流切面,而面向缓冲区的IO则使我们能够看到所有的水(数据的上下文),也就是说在缓冲区中获取某项数据的前一项数据或者是后一项数据十分方便。这种便利是有代价的,因为我们必须管理好缓冲区,这包括不能让新的数据覆盖了缓冲区中还没有被处理的有用数据;将缓冲区中的数据正确的分块,分清哪些被处理过哪些还没有等等。

阻塞和非阻塞

  1. Java IO是阻塞的,如果在一次读写数据调用时数据还没有准备好,或者目前不可写,那么读写操作就会被阻塞直到数据准备好或目标可写为止。
  2. 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的区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Seata 环境搭建部署过程

    Seata 环境搭建部署过程

    Seata是一个分布式事务,seata服务端也是一个微服务,需要和其他微服务一样需要注册中心和配置中心,这篇文章主要介绍了Seata 环境搭建,需要的朋友可以参考下
    2022-10-10
  • Java 设计模式以虹猫蓝兔的故事讲解单例模式

    Java 设计模式以虹猫蓝兔的故事讲解单例模式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
    2022-03-03
  • Mybatis-plus通过添加拦截器实现简单数据权限

    Mybatis-plus通过添加拦截器实现简单数据权限

    系统需要根据用户所属的公司,来做一下数据权限控制,具体一点,就是通过表中的company_id进行权限控制,项目使用的是mybatis-plus,所以通过添加拦截器的方式,修改查询sql,实现数据权限,本文就通过代码给大家详细的讲解一下,需要的朋友可以参考下
    2023-08-08
  • Spring Cloud Alibaba Nacos Config加载配置详解流程

    Spring Cloud Alibaba Nacos Config加载配置详解流

    这篇文章主要介绍了Spring Cloud Alibaba Nacos Config配置中心实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-07-07
  • Spring Bean的定义及三种创建方式

    Spring Bean的定义及三种创建方式

    本文主要介绍了Spring容器获取Bean的9种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java Socket编程实例(四)- NIO TCP实践

    Java Socket编程实例(四)- NIO TCP实践

    这篇文章主要讲解Java Socket编程中NIO TCP的实例,希望能给大家做一个参考。
    2016-06-06
  • Java DecimalFormat 保留小数位及四舍五入的陷阱介绍

    Java DecimalFormat 保留小数位及四舍五入的陷阱介绍

    这篇文章主要介绍了Java DecimalFormat 保留小数位及四舍五入的陷阱,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 一名Java高级工程师需要学什么?

    一名Java高级工程师需要学什么?

    作为一名Java高级工程师需要学什么?如何成为一名合格的工程师,这篇文章给了你较为详细的答案,需要的朋友可以参考下
    2017-08-08
  • JWT在OpenFeign调用中进行令牌中继详解

    JWT在OpenFeign调用中进行令牌中继详解

    Feign是一个声明式的Web Service客户端,是一种声明式、模板化的HTTP客户端。而OpenFeign是Spring Cloud 在Feign的基础上支持了Spring MVC的注解,如@RequesMapping等等,这篇文章主要给大家介绍了关于JWT在OpenFeign调用中进行令牌中继的相关资料,需要的朋友可以参考下
    2021-10-10
  • Java编程子类能否重写父类的静态方法探索

    Java编程子类能否重写父类的静态方法探索

    关于子类能否重写父类的静态方法,对像我这种初级的编程爱好者来说仍是值得讨论的一件事,下面我们通过具体实例,对此问题进行简单的探索。
    2017-10-10

最新评论