IO 和NIO有什么区别?

news/2025/2/27 6:43:55/

在 Java 中,IO(Input/Output)即传统的标准输入输出,NIO(New Input/Output)是 Java 1.4 引入的新的 IO 库,它们之间存在多方面的区别,详细总结如下:

  1. 数据读取方式
    • IO:传统的 IO 是面向流的,数据的读取和写入是按顺序进行的,以流的形式一个字节一个字节或一个字符一个字符地处理。比如使用 FileInputStream 读取文件时,需要不断地从流中读取字节,直到读取完整个文件内容。这种方式在处理大文件时可能效率较低,因为每次读取的数据量较小,频繁的读写操作会增加系统开销。
    • NIO:NIO 是面向缓冲区的,数据读取到一个缓冲区中,然后可以对缓冲区中的数据进行处理。缓冲区就像一个容器,可以一次性存储一定数量的数据。例如,ByteBuffer 是 NIO 中常用的缓冲区,通过对缓冲区的操作(如读取、写入、翻转、复位等)来处理数据。这种方式更加灵活,提高了数据处理的效率,尤其在处理大文件时优势明显。
  2. 阻塞与非阻塞
    • IO:传统的 IO 操作是阻塞式的。当一个线程执行 IO 操作时(如读取文件或网络套接字),该线程会一直阻塞,直到操作完成。例如,当使用 read() 方法从输入流中读取数据时,线程会等待数据的到来,在数据到达之前,线程一直处于阻塞状态,无法执行其他任务。这会导致线程资源的浪费,尤其是在处理多个并发请求时,可能会造成性能瓶颈。
    • NIO:NIO 中的非阻塞模式允许线程在执行 IO 操作时不会被阻塞。线程可以在发送一个读取或写入请求后立即返回,继续执行其他任务。例如,在使用 Selector(选择器)时,可以注册多个通道(如 SocketChannel)到选择器上,并设置为非阻塞模式。选择器会不断地轮询这些通道,当某个通道有数据可读或可写时,才会通知线程进行相应的操作。这样可以提高线程的利用率,实现更高效的并发处理。
  3. 通道(Channel)和流(Stream)
    • IO:在传统的 IO 中,使用流来进行数据的读写操作。流是单向的,分为输入流和输出流,分别用于读取数据和写入数据。例如,FileInputStream 用于从文件中读取数据,FileOutputStream 用于向文件中写入数据。流的操作相对简单直接,但不够灵活。
    • NIO:NIO 引入了通道的概念,通道是双向的,可以同时进行数据的读取和写入操作。通道可以看作是连接程序和数据源头的桥梁,如 FileChannel 用于文件的读写操作,SocketChannel 用于网络套接字的数据传输。通道不能直接读写数据,需要配合缓冲区来使用,通过将数据从通道读取到缓冲区或从缓冲区写入通道来实现数据的传输。
  4. Selector(选择器)
    • IO:传统的 IO 没有选择器的概念,对于多个并发的 IO 操作,需要为每个操作创建一个独立的线程来处理,这样会导致线程数量过多,增加系统的开销和管理难度。
    • NIO:NIO 中的选择器是一个非常重要的组件,它可以监听多个通道的事件(如可读、可写、连接等)。一个线程可以通过选择器同时管理多个通道,当某个通道发生感兴趣的事件时,选择器会通知线程进行相应的处理。通过选择器,NIO 可以实现单线程处理多个并发的 IO 操作,大大提高了系统的并发性能和资源利用率。
  5. 性能和适用场景
    • IO:传统的 IO 适用于处理简单的、数据量较小的、对实时性要求不高的 IO 操作。例如,在一些小型应用程序中,读取配置文件或写入简单的日志文件等场景,使用传统的 IO 就足够了。由于其阻塞式的特性,在处理大量并发请求时性能较差。
    • NIO:NIO 适用于处理高并发、大数据量的 IO 操作,如网络服务器中的数据传输、大规模文件的读写等场景。NIO 的非阻塞模式和选择器机制使得它能够高效地处理多个并发连接,减少线程的创建和管理开销,提高系统的吞吐量和响应速度。

综上所述,IO 和 NIO 在数据读取方式、阻塞特性、使用的概念以及性能和适用场景等方面都存在明显的区别。在实际开发中,需要根据具体的需求和场景选择合适的 IO 方式。


http://www.ppmy.cn/news/1575197.html

相关文章

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

使用 Docker 管理 Alpine 镜像的完整指南

在这篇博客中,我们将深入探讨如何使用 Docker 命令来拉取、保存和加载 Docker 镜像。我们将以 alpine 镜像为例,展示每个步骤的详细操作和输出示例。【因特殊原因可以借助外网下载镜像,然后导入到本地的服务器】 1. 拉取镜像 (docker pull) …

当AI搜索撕开传统搜索的裂缝,警惕AI搜索的“信息茧房”

大家好,我是Shelly,一个专注于输出AI工具和科技前沿内容的AI应用教练,体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具,拥抱AI时代的到来。 人工智能&AIGC术语100条 Shelly聊AI-重…

基于 JavaWeb 的 SSM+Maven 微信小程序快递柜管理系统设计和实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

京准电钟:NTP精密时钟服务器在自动化系统中的作用

京准电钟:NTP精密时钟服务器在自动化系统中的作用 京准电钟:NTP精密时钟服务器在自动化系统中的作用 NTP精密时钟服务器在自动化系统中的作用非常重要,特别是在需要高精度时间同步的场景中。NTP能够提供毫秒级的时间同步精度,这…

Lua的for循环中ipairs和pairs的区别

ipairs 主要用于便利连续的数字键,遍历table中遍历数组形式的表,下面是代码示例 local t {a 1,7, b 2, c 3,4,5,6} for k, v in ipairs(t) doprint(k, v) end输出的结果是: Pairs 主要用于遍历所有的键,包括非数字键,但是非数字键的顺序可能不同,下面是代码…

自动驾驶泊车算法详解(一)

自动驾驶泊车算法是自动驾驶技术中的重要组成部分,主要用于实现车辆在复杂场景下的自动泊车功能(如垂直泊车、侧方位泊车、斜列泊车等)。其核心目标是通过感知、规划和控制技术,使车辆在无人工干预的情况下安全、高效地完成泊车动…

机试刷题_NC17 最长回文子串【python】

NC17 最长回文子串 动态规划思路 1.定义状态: 设 dp[i][j] 表示字符串 A 从第 i 个字符到第 j 个字符是否为回文子串。 如果是回文子串,dp[i][j] True,否则为 False。 2.状态转移方程: 如果 A[i] A[j],并且 dp[i1][…