当前位置: 首页 > news >正文

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:服务器端通道准备好接受新的客户端连接。

http://www.cnnetsun.cn/news/65208.html

相关文章:

  • 测试环境管理的最佳实践
  • Miniconda环境下安装PyTorch GPU版的完整流程
  • AI推理的“哥白尼革命”!何恺明团队推翻LLM,将抽象推理重新定义为视觉问题
  • 深度学习训练器框架全面对比指南
  • 火山引擎AI大模型新玩法:结合vLLM实现高效推理
  • 16、GTK+ 样式定制全解析
  • LobeChat是否支持Service Worker?离线访问能力构建
  • 重学计算机基础013:减法运算的底层逻辑——为什么没有“减法器”?
  • apk pure安全性争议下,本地大模型成新趋势
  • LobeChat能否支持NFT头像展示?个性化形象设定
  • LobeChat + Kubernetes:大规模部署AI前端界面的可行路径
  • 20万以内家用新能源SUV怎么选?纯电动车型主动安全系统深度对比
  • 基于28DR+VU13P的宽带高速信号处理板
  • AutoGPT镜像上线促销:限时赠送免费Token额度
  • 达人内容乱+不合规?KOL/KOS/KOC/KOC/KOX内容协同+合规管控,品牌调性不跑偏
  • 解锁优质创意素材:这四个专业平台值得收藏
  • 毕设分享 深度学习遮挡下的人脸识别(源码+论文)
  • Python UV搭配Miniconda:下一代包管理体验
  • 实验室装修,怎样做更省心?
  • Redis多数据源配置指南
  • AutoGPT支持ONNX Runtime部署了吗?跨框架兼容测试
  • 零基础小白网络安全入行清单:学技术前,先搞定这6件“小事”
  • 计算机毕业设计springboot小区送货系统 基于SpringBoot的社区末端智能配送平台 面向住宅区的 轻量级电商物流管理系统
  • GitHub组织账号管理Qwen3-32B项目协作开发流程
  • 毕设项目分享 基于大数据的招聘职业爬取与分析可视化
  • vLLM镜像实测:连续批处理让Qwen推理效率翻倍
  • LabVIEW 携手 YOLOv8:全方位视觉处理的奇妙之旅
  • 某雷赛86闭环步进驱动方案-HBS86H整体方案及原理图、PCB、无错无警告代码打包
  • 【从0到1学RabbitMQ】十分钟上手 RabbitMQ:Docker 部署 + Spring Boot 自动化配置全攻略
  • 【论文笔记•(多智能体)】A Knowledge-driven Adaptive Collaboration of LLMs for Enhancing Medical Decision-making