在Java里NIO和IO有什么不同

来源:苹果APP网作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《在Java里NIO和IO有什么不同》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《在Java里NIO和IO有什么不同》有用,将其分享出去将是对创作者最好的鼓励。

Java中的IO和NIO都是用于处理输入输出操作的API,但两者的设计思路和应用场景存在较大差异,理解它们的区别有助于开发者在实际项目中做出更合适的技术选型。

在Java里NIO和IO有什么不同

Java IO与NIO的核心概念差异

传统的Java IO是面向流的,而NIO是面向缓冲区的。IO的操作方式是一次处理一个字节或者字符的数据流,数据只能按顺序读取或者写入,不能前后移动流中的数据。而NIO则是通过缓冲区来操作数据,数据会先读取到缓冲区中,开发者可以在缓冲区中随意移动指针来读取或者修改数据,操作更加灵活。

另外,IO是阻塞的,而NIO支持非阻塞模式。在使用传统IO进行读取操作时,如果数据源没有数据可读,线程会一直阻塞等待,直到有数据到来或者发生异常。而NIO的非阻塞模式下,线程发起读取请求后,如果没有数据可读,会立刻返回,不会阻塞线程,线程可以去处理其他任务。

核心组件对比

传统IO的核心组件主要是InputStreamOutputStreamReaderWriter这些流相关的类,操作逻辑相对简单直接。而NIO引入了几个新的核心组件:

  • Channel(通道):通道是数据传输的载体,和流类似,但通道可以双向传输数据,而流只能是单向的,要么是输入流要么是输出流。常见的通道有FileChannelSocketChannelServerSocketChannel等。
  • Buffer(缓冲区):缓冲区是存储数据的中间容器,所有数据都是通过缓冲区来和通道交互的。常见的缓冲区有ByteBufferCharBuffer等,其中ByteBuffer是最常用的。
  • Selector(选择器):选择器是NIO实现多路复用的核心,一个选择器可以监听多个通道的事件,比如连接就绪、读就绪、写就绪等。只需要一个线程就可以管理多个通道,大大减少了线程资源的消耗。

代码实现差异示例

传统IO读取文件示例

下面是使用传统IO读取文件内容的代码示例:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class TraditionalIORead {
    public static void main(String[] args) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream("test.txt");
            int data;
            // 循环读取字节,直到返回-1表示读取结束
            while ((data = inputStream.read()) != -1) {
                // 将读取到的字节转为字符输出
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流释放资源
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

NIO读取文件示例

下面是使用NIO读取相同文件内容的代码示例:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class NIORead {
    public static void main(String[] args) {
        FileChannel fileChannel = null;
        try {
            // 获取文件的通道
            fileChannel = FileChannel.open(Paths.get("test.txt"), StandardOpenOption.READ);
            // 创建缓冲区,大小为1024字节
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead;
            // 循环读取数据到缓冲区
            while ((bytesRead = fileChannel.read(buffer)) != -1) {
                // 切换缓冲区为读模式
                buffer.flip();
                // 读取缓冲区中的数据
                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }
                // 清空缓冲区,准备下次读取
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭通道释放资源
            if (fileChannel != null) {
                try {
                    fileChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Java IO模型的演进过程

Java的IO模型随着版本迭代不断演进,从最开始的BIO到NIO,再到后来的AIO,逐步解决了不同场景下的性能问题。

BIO(阻塞IO)

BIO就是传统的Java IO,属于同步阻塞模型。每个连接都需要一个独立的线程来处理,当并发量较高时,会创建大量的线程,线程的创建和上下文切换会带来很大的性能开销,因此BIO只适合连接数较少的场景。

NIO(非阻塞IO)

Java 1.4引入了NIO,属于同步非阻塞模型,通过选择器实现了多路复用,一个线程可以管理多个连接,大大减少了线程的数量,适合连接数多但连接时间较短的场景,比如聊天服务器、即时通讯系统等。

AIO(异步IO)

Java 1.7引入了AIO,属于异步非阻塞模型,异步IO的操作是由操作系统完成的,完成后会回调通知应用程序,不需要应用程序主动去查询状态。AIO适合连接数多且连接时间长的场景,比如文件读写、复杂的网络请求等,但目前应用范围相对NIO来说更小一些。

适用场景对比

传统IO适合处理数据量小、连接数少的场景,比如简单的文件读写、小规模的客户端服务端通信,它的API简单易懂,开发成本低。

NIO适合处理高并发、连接数多但单个连接的数据传输量不大的场景,比如高性能的网络服务器、网关系统等,能够充分利用系统资源,提升程序的吞吐量。

对比维度传统IONIO
操作方式面向流,顺序操作面向缓冲区,可随机操作
阻塞特性阻塞支持非阻塞
线程模型一个连接一个线程一个线程管理多个连接
核心组件流(InputStream/OutputStream等)通道、缓冲区、选择器
适用场景连接数少、数据量小高并发、连接数多

总结

Java的NIO和IO在设计理念和使用方式上有明显的区别,IO是面向流的阻塞模型,适合简单场景;NIO是面向缓冲区的非阻塞模型,支持多路复用,适合高并发场景。开发者在实际开发中,需要根据具体的业务场景和性能需求,选择合适的IO模型,才能最大化发挥程序的性能优势。

Java_NIOJava_IOIO模型阻塞IO非阻塞IO修改时间:2026-07-23 11:30:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。