news 2026/7/13 22:13:11

Java 中 NIO 和IO 的区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 中 NIO 和IO 的区别

在Java 中,IO(input/output)和 NIO(new Input/output) 是两种不同的输入输出处理机制。它们各自有不同的设计理念和使用场景,理解这两者的区别对于优化性能、提高应用的响应速度非常重要。

一、IO(传统输入输出)

IO是java最早的输入输出方式,通过流(Stream)来读写数据。主要包括字节流和字符流。通过阻塞式的操作来实现数据的读写。
1、特点
阻塞式(Blocking):每次调用读写操作时,线程会被阻塞,直到数据完全读取或写入。也就是说,io操作会让线程一直等待,知道数据准备好。

同步:每个线程只能处理一个连接,不能同时处理多个客户端请求。需要多个线程来同时处理多个IO操作。

易于使用:传统IO库简单直观适合小型应用或数据量较小的场景。

数据流模型:基于流模型,数据按顺序从源流传输到目标流。

2、主要类

  • inputStream 和 outputStream字节流
  • reader 和 writer:字符流

3、示例:

// 读取文件内容FileInputStreamfis=newFileInputStream("file.txt");intdata;while((data=fis.read())!=-1){System.out.print((char)data);}fis.close();

二、NIO(new input/output)

NIO 是 Java 在 JDK 1.4 中引入的新的 IO 库,相较于传统 IO,它提供了非阻塞式的 I/O 操作。NIO 使用 通道(Channel) 和 缓冲区(Buffer) 来进行数据的读写。
1、特点:
非阻塞式(Non-blocking):NIO 通过Selector(选择器)和Channel(通道)来支持非阻塞I/O操作。允许线程在等待数据时做其他事情,一个线程可以处理多个通道上的I/O操作。
异步:非阻塞I/O操作使得程序能够在等待I/O操作完成的同时,继续执行其他任务,从而提高了系统性能。
支持大文件和高并发:NIO更适合处理大量数据和高并发请求。
NIO 是 Java 在 JDK 1.4 中引入的新的 IO 库,相较于传统 IO,它提供了非阻塞式的 I/O 操作。NIO 使用 通道(Channel) 和 缓冲区(Buffer) 来进行数据的读写。
基于事件驱动:NIO 通过 Selector 机制(监听多个通道上的事件),可以让一个线程管理多个 I/O 操作。

2、主要类:

  • Channel(通道):可以用来读写数据,常见的通道类有 FileChannel、SocketChannel、DatagramChannel 等。

  • Buffer(缓冲区):数据的读写都发生在缓冲区中,通过 ByteBuffer、CharBuffer 等类来管理数据。

  • Selector(选择器):通过选择器,一个线程可以管理多个通道的 I/O 操作。

3、示例:

// 使用 NIO 读取文件内容Pathpath=Paths.get("file.txt");Charsetcharset=Charset.forName("UTF-8");try(BufferedReaderreader=Files.newBufferedReader(path,charset)){Stringline;while((line=reader.readLine())!=null){System.out.println(line);}}

三、IO 和 NIO 的区别

特点IONIO
阻塞/非阻塞阻塞式,读写时会阻塞当前线程非阻塞式,线程可以在等待 I/O 时继续做其他工作
模型基于流(Stream)的模型基于通道(Channel)和缓冲区(Buffer)模型
适用场景适用于少量数据或简单应用适用于大规模数据、高并发、长时间连接等场景
多线程支持每个线程处理一个 I/O 操作,需要多个线程处理多个请求一个线程可以处理多个通道上的 I/O 操作
数据读取方式按顺序读取,通过流逐字节或逐行处理数据数据通过缓冲区(Buffer)批量读取和写入
使用难度简单易用,学习曲线较低相对复杂,学习曲线较高,需要理解缓冲区、选择器等概念
性能在高并发场景下性能较低高性能,尤其适用于高并发、大文件处理等场景

四、NIO 中通道和选择器的概念

一、通道(Channel)

通道 是 NIO 中用于数据传输的主要组件。它类似于传统 I/O 中的流,但在设计上更为灵活和高效。通道是双向的,即可以同时进行读取和写入操作。

1️⃣通道的概念

通道(Channel)代表了连接 I/O 操作的媒介。你可以通过通道来执行读取和写入操作,通道本身并不直接存储数据,而是通过缓冲区(Buffer)来与数据交互。

2️⃣通道的主要类型

NIO 中的通道有多种类型,常见的有:

  • FileChannel:用于文件 I/O 操作,提供文件的读取和写入功能。

    • 示例:用于读取文件中的字节或将数据写入文件。
  • SocketChannel:用于网络 I/O 操作,通过 TCP 协议与远程计算机进行通信。

    • 示例:用于客户端与服务器之间的数据传输。
  • DatagramChannel:用于通过 UDP 协议进行网络 I/O 操作。

    • 示例:用于实时性要求较高的通信,像 DNS 查询、VoIP(语音通信)等。
  • ServerSocketChannel:用于服务器端监听并接受客户端连接请求。

    • 示例:用来实现一个基于 NIO 的服务器。

3️⃣通道的基本操作

通道的基本操作包括 读 和 写,但是通道本身并不直接处理数据,它通过 缓冲区(Buffer) 来执行数据的存储和传输。

  • 读取数据:read() 方法会把数据从通道中读取到缓冲区。

  • 写入数据:write() 方法会把缓冲区中的数据写入到通道中。

// 示例:使用 FileChannel 读取文件FileChannelchannel=newFileInputStream("file.txt").getChannel();ByteBufferbuffer=ByteBuffer.allocate(1024);intbytesRead=channel.read(buffer);// 读取文件内容到缓冲区

4️⃣ 通道与流的区别

  • 流(Stream):一次只能操作一个方向的数据传输(只能读取或写入)。

  • 通道(Channel):可以双向操作数据(既能读也能写)。

二、选择器(Selector)

选择器 是 NIO 中用于实现多路复用(Multiplexing)的核心组件。它允许一个线程同时管理多个通道(Channel),并能够处理多个 I/O 操作,而不需要为每个通道创建独立的线程。

1️⃣选择器的概念

选择器(Selector)是一个多路复用器,用于检查多个通道的状态。通过选择器,线程可以监控多个通道上的事件(如是否可读、可写、连接已完成等),当事件发生时,线程才会处理这些通道上的操作。

2️⃣选择器的工作流程

注册通道:将通道注册到选择器,并指定感兴趣的事件(如 OP_READ、OP_WRITE、OP_CONNECT 等)。

轮询事件:选择器不断轮询各个注册的通道,检查它们的状态,若某个通道准备好进行 I/O 操作(如数据可以读取或写入),就会将该通道加入到已选择的通道列表中。

处理 I/O 操作:当事件发生时,线程可以对该通道执行相应的 I/O 操作。

3️⃣选择器的核心方法

open():创建一个新的选择器。

select():阻塞并等待通道事件的发生,返回就绪的通道数。

selectedKeys():返回一个包含已就绪通道的集合,可以通过它来遍历就绪的通道并进行操作。

// 示例:使用 Selector 监听通道事件Selectorselector=Selector.open();ServerSocketChannelserverChannel=ServerSocketChannel.open();serverChannel.configureBlocking(false);// 设置为非阻塞模式serverChannel.register(selector,SelectionKey.OP_ACCEPT);while(true){selector.select();// 阻塞直到有事件发生Set<SelectionKey>selectedKeys=selector.selectedKeys();for(SelectionKeykey:selectedKeys){if(key.isAcceptable()){// 处理连接请求}elseif(key.isReadable()){// 处理读取事件}selectedKeys.remove(key);}}

4️⃣选择器的事件类型

OP_READ:通道可读,数据可以从通道读取。

OP_WRITE:通道可写,数据可以写入通道。

OP_CONNECT:连接已经建立。

OP_ACCEPT:服务器端通道准备好接受新的客户端连接。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 14:43:20

LobeChat能否运行TensorFlow.js模型?浏览器内推理尝试

LobeChat 能否运行 TensorFlow.js 模型&#xff1f;浏览器内推理尝试 在现代 AI 应用的演进中&#xff0c;一个越来越清晰的趋势是&#xff1a;智能正在从云端向终端迁移。用户不再满足于“发个问题、等几秒、收个答案”的交互模式&#xff0c;而是期望更实时、更私密、更具上下…

作者头像 李华
网站建设 2026/7/13 6:18:44

LobeChat插件系统全解析:如何扩展你的AI助手功能?

LobeChat插件系统全解析&#xff1a;如何扩展你的AI助手功能&#xff1f; 在今天的AI应用开发中&#xff0c;一个聊天界面是否“聪明”&#xff0c;早已不再只取决于背后的大模型能力。真正决定用户体验的&#xff0c;往往是前端能否灵活调用外部工具、实时获取数据、处理文件&…

作者头像 李华
网站建设 2026/7/13 3:57:34

当AI遇上售后服务:一场关于效率与体验的革命

从"人工排队"到"秒级响应"的蜕变 记得去年双十一&#xff0c;我朋友小张的电商店铺遭遇了一场"售后灾难"。订单量暴增300%&#xff0c;客服团队24小时轮班也应付不过来&#xff0c;客户投诉像雪花一样飞来。最夸张的时候&#xff0c;一个客户要…

作者头像 李华
网站建设 2026/7/11 10:21:31

Postman接口测试:如何导入 swagger 接口文档?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快在使用 postman 做接口测试过程中&#xff0c;测试工程师会往界面中填入非常多的参数&#xff0c;包括 url 地址&#xff0c;请求方法&#xff0c;消息头和消息体等…

作者头像 李华
网站建设 2026/7/11 16:52:22

LobeChat能否检测敏感内容?内置过滤机制介绍

LobeChat 的敏感内容检测能力解析&#xff1a;架构、实践与安全设计 在AI助手逐渐渗透到企业服务和个人工具的今天&#xff0c;一个看似简单却至关重要的问题浮现出来&#xff1a;当用户输入“如何绕过审查”或模型输出带有偏见的内容时&#xff0c;系统能否及时识别并拦截&am…

作者头像 李华
网站建设 2026/7/10 17:06:07

陶瓷基板介电频谱测试的核心意义(从微观到宏观)

陶瓷基板的介电频谱测试是一项跨越材料科学与高频电子工程的关键技术。它不仅仅是简单的“测数值”&#xff0c;而是通过在宽频率范围内测量材料的复介电常数&#xff0c;来揭示材料内部微观极化机制&#xff0c;并为高频高速电路的设计提供物理依据。1. 核心价值&#xff1a;从…

作者头像 李华