JAVA IO和NIO的主要区别及使用说明

 更新时间:2025年09月21日 15:48:50   作者:night_gu  
Java IO(BIO)阻塞式,逐字节流处理;NIO非阻塞,基于缓冲区和通道实现多路复用,单线程管理多连接,适合高并发网络编程,IO代码简单但性能低,NIO性能高但复杂度增加,选择需权衡开发效率与性能需求

JAVA IO和NIO的主要区别

IO(BIO)是阻塞的,NIO是非阻塞的

传统IO在读写数据时会阻塞线程,直到数据准备好或完全写入。

例如,InputStream.read()会一直阻塞,直到有数据可读。NIO通过通道(Channel)和选择器(Selector)实现非阻塞模式,线程可以处理其他任务,无需等待数据就绪。

IO面向流,NIO面向缓冲区

IO基于流(Stream)模型,数据只能单向流动(输入流或输出流)。NIO基于缓冲区(Buffer)和通道,数据先读写到缓冲区,再通过通道双向传输,支持更灵活的数据处理。

NIO支持多路复用

NIO通过Selector监控多个通道的事件(如连接、读写),单线程即可管理多个连接,适合高并发场景。传统IO每个连接需独立线程处理,资源消耗大。

核心组件对比

IO的核心类

  • InputStream/OutputStream:字节流基类。
  • Reader/Writer:字符流基类。

NIO的核心类

  • Buffer:数据存储容器(如ByteBuffer)。
  • Channel:双向数据传输通道(如FileChannelSocketChannel)。
  • Selector:监听多个通道的事件。

性能与应用场景

IO适用场景

  • 连接数少、数据量大的场景(如文件读写)。
  • 代码简单,无需复杂并发控制。

NIO适用场景

  • 高并发、低延迟的网络应用(如聊天.服务器)。
  • 需要同时管理大量连接(如Web服务器)。

代码示例对比

传统IO读取文件

try (FileInputStream fis = new FileInputStream("file.txt")) {
    int data;
    while ((data = fis.read()) != -1) {
        System.out.print((char) data);
    }
}

NIO读取文件

try (FileChannel channel = FileChannel.open(Paths.get("file.txt"))) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (channel.read(buffer) != -1) {
        buffer.flip();
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        buffer.clear();
    }
}

总结

  • IO:简单易用,适合同步阻塞操作。
  • NIO:高性能、非阻塞,适合高并发网络编程。
  • 选择依据:根据项目需求权衡开发效率和性能要求。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springboot使用校验框架validation校验的示例

    springboot使用校验框架validation校验的示例

    这篇文章主要介绍了springboot使用校验框架validation校验的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • Spring Boot如何排除自动加载数据源

    Spring Boot如何排除自动加载数据源

    这篇文章主要介绍了Spring Boot如何排除自动加载数据源,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java异常处理3个避坑神操作总结(告别崩溃式报错)

    Java异常处理3个避坑神操作总结(告别崩溃式报错)

    日常Java开发中,有些细节看似微小,却能大幅影响代码质量,这篇文章主要介绍了Java异常处理3个避坑神操作总结的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-04-04
  • Java类中字段可以不赋予初始值的原因分析

    Java类中字段可以不赋予初始值的原因分析

    这篇文章主要介绍了Java类中字段可以不赋予初始值的原因分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Spring boot文件路径映射配置代码实例

    Spring boot文件路径映射配置代码实例

    这篇文章主要介绍了Spring boot文件路径映射配置代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • java 回调机制的实例详解

    java 回调机制的实例详解

    这篇文章主要介绍了java 回调机制的实例详解的相关资料,希望通过本文的示例能帮助到大家理解使用回调机制,需要的朋友可以参考下
    2017-09-09
  • Springboot上传文件的同时传递参数用对象接收的问题及解决方案

    Springboot上传文件的同时传递参数用对象接收的问题及解决方案

    在Spring Boot中,若接口需同时接收文件和其他参数,应将文件用@RequestParam标注,其他参数封装对象并用@Validated校验,避免参数绑定冲突,本文给大家介绍Springboot上传文件的同时传递参数用对象接收,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • 关于RabbitMQ的Channel默认线程

    关于RabbitMQ的Channel默认线程

    这篇文章主要介绍了关于RabbitMQ的Channel默认线程,通过jvm工具观察rabbitmq的线程使用情况,发现生产者每发一条消息,消费者这边就会创建一条线程,言下之意,一个channel当消息来到时就会异步处理这些消息,需要的朋友可以参考下
    2023-09-09
  • Java定时器Timer的源码分析

    Java定时器Timer的源码分析

    通过源码分析,我们可以更深入的了解其底层原理。本文将通过Timer的源码,带大家深入了解Java Timer的使用,感兴趣的小伙伴可以了解一下
    2022-11-11
  • java -jar指定外部配置文件操作步骤

    java -jar指定外部配置文件操作步骤

    这篇文章主要给大家介绍了关于java -jar指定外部配置文件的相关资料,需要的朋友可以参考下
    2023-11-11

最新评论