Java IO 和 NIO 的基本概念和 API

一、 Java IO (Blocking IO)

  1. 基本概念:

    • Java IO 是 Java 平台提供的用于进行输入和输出操作的 API。
    • Java IO 基于 流 (Stream) 的模型,数据像水流一样从一个地方流向另一个地方。
    • Java IO 主要是 阻塞式 I/O (Blocking I/O),即线程在执行 I/O 操作时会被阻塞,直到操作完成。
    • 传统IO指的是java.io包下的部分组件(File, InputStream, OutputStream, Reader, Writer)。
  2. IO 流的分类:

    • 按数据传输方向:

      • 输入流 (Input Stream): 用于从数据源读取数据(例如,从文件、网络连接、键盘等)。 以 InputStreamReader 作为基类。
      • 输出流 (Output Stream): 用于将数据写入到目标(例如,写入到文件、网络连接、控制台等)。 以 OutputStreamWriter 作为基类。
    • 按数据传输单位:

      • 字节流 (Byte Stream): 以字节 (8 bits) 为单位进行数据传输。 以 InputStreamOutputStream 作为基类。 适用于处理二进制数据(例如,图片、音频、视频等)。
      • 字符流 (Character Stream): 以字符 (16 bits) 为单位进行数据传输。 以 ReaderWriter 作为基类。 适用于处理文本数据。
  3. 核心类和接口:

    • InputStream (字节输入流):

      • FileInputStream: 从文件中读取字节。
      • ByteArrayInputStream: 从字节数组中读取字节。
      • ObjectInputStream: 从对象流中读取对象。
      • BufferedInputStream: 带缓冲的字节输入流,提高读取效率。
    • OutputStream (字节输出流):

      • FileOutputStream: 向文件中写入字节。
      • ByteArrayOutputStream: 向字节数组中写入字节。
      • ObjectOutputStream: 向对象流中写入对象。
      • BufferedOutputStream: 带缓冲的字节输出流,提高写入效率。
    • Reader (字符输入流):

      • FileReader: 从文件中读取字符。
      • CharArrayReader: 从字符数组中读取字符。
      • BufferedReader: 带缓冲的字符输入流,提高读取效率。
      • InputStreamReader: 将字节输入流转换为字符输入流(需要指定字符编码)。
    • Writer (字符输出流):

      • FileWriter: 向文件中写入字符。
      • CharArrayWriter: 向字符数组中写入字符。
      • BufferedWriter: 带缓冲的字符输出流,提高写入效率。
      • OutputStreamWriter: 将字节输出流转换为字符输出流(需要指定字符编码)。
    • File: 表示文件或目录的抽象表示。

  4. IO 操作流程 (以读取文件为例):

    1. 创建 File 对象: 指定要读取的文件路径。
    2. 创建 FileInputStream 对象:File 对象作为参数传递给 FileInputStream 的构造方法,创建一个 FileInputStream 对象。
    3. 创建 BufferedInputStream 对象 (可选):FileInputStream 对象作为参数传递给 BufferedInputStream 的构造方法,创建一个 BufferedInputStream 对象,提高读取效率。
    4. 读取数据: 使用 read() 方法从输入流中读取数据。
    5. 关闭流: 在完成读取操作后,务必关闭输入流,释放资源(先关闭 BufferedInputStream,再关闭 FileInputStream)。
  5. 代码示例 (读取文件内容):

    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;public class IOExample {public static void main(String[] args) {File file = new File("test.txt"); // 替换为你的文件路径try (FileInputStream fis = new FileInputStream(file);BufferedInputStream bis = new BufferedInputStream(fis)) { // 使用 try-with-resources 语句,自动关闭流byte[] buffer = new byte[1024];int bytesRead;while ((bytesRead = bis.read(buffer)) != -1) {// 处理读取到的数据String data = new String(buffer, 0, bytesRead);System.out.print(data);}} catch (IOException e) {e.printStackTrace();}}
    }
    

二、 Java NIO (Non-blocking IO)

  1. 基本概念:

    • Java NIO 是 Java 1.4 引入的一组新的 I/O API,旨在提供高性能、非阻塞的 I/O 操作。
    • NIO 使用 通道 (Channel)缓冲区 (Buffer) 的模型,而不是流。
    • NIO 主要是 非阻塞式 I/O (Non-blocking I/O),即线程在执行 I/O 操作时不会被阻塞,而是可以执行其他任务。
    • NIO 使用 选择器 (Selector) 来监听多个通道的事件,实现单线程管理多个连接。
  2. 核心组件:

    • 通道 (Channel):

      • 通道类似于流,但可以进行双向数据传输(既可以读取数据,也可以写入数据)。
      • 常见的通道:
        • FileChannel: 用于文件 I/O。
        • SocketChannel: 用于 TCP 网络 I/O (客户端)。
        • ServerSocketChannel: 用于 TCP 网络 I/O (服务器端)。
        • DatagramChannel: 用于 UDP 网络 I/O。
    • 缓冲区 (Buffer):

      • 缓冲区是用于存储数据的容器,本质上是一个字节数组 (ByteBuffer) 或字符数组 (CharBuffer)。
      • NIO 使用缓冲区进行数据传输,而不是直接从通道读取数据或向通道写入数据。
      • 常见的缓冲区:
        • ByteBuffer: 字节缓冲区。
        • CharBuffer: 字符缓冲区。
        • ShortBuffer: 短整型缓冲区。
        • IntBuffer: 整型缓冲区。
        • LongBuffer: 长整型缓冲区。
        • FloatBuffer: 浮点型缓冲区。
        • DoubleBuffer: 双精度浮点型缓冲区。
    • 选择器 (Selector):

      • 选择器允许单个线程监听多个通道的事件(例如连接建立、数据可读、数据可写等)。
      • 使用选择器可以避免为每个连接创建一个线程,从而提高并发性能。
  3. NIO 操作流程 (以读取 SocketChannel 数据为例):

    1. 创建 ServerSocketChannel 监听客户端连接。
    2. 创建 SocketChannel 接受客户端连接。
    3. SocketChannel 注册到 Selector 指定要监听的事件(例如 OP_READ, OP_WRITE, OP_CONNECT, OP_ACCEPT)。
    4. 创建 ByteBuffer 用于存储读取到的数据。
    5. 调用 selector.select() 方法: 阻塞等待有事件发生的通道。
    6. 获取就绪的通道: selector.selectedKeys() 返回所有就绪通道的集合。
    7. 处理事件: 遍历就绪通道的集合,根据不同的事件类型执行相应的操作(例如读取数据、写入数据)。
    8. 读取数据: 调用 channel.read(buffer) 从通道读取数据到缓冲区。
    9. 处理缓冲区数据: 从缓冲区读取数据并进行处理。
    10. 关闭通道和选择器: 在完成操作后,务必关闭通道和选择器,释放资源。
  4. 代码示例 (使用 SocketChannel 读取数据):

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SocketChannel;public class NIOExample {public static void main(String[] args) throws IOException {// 1. 创建 SocketChannelSocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("www.example.com", 80));socketChannel.configureBlocking(false); // 设置为非阻塞模式// 2. 创建 ByteBufferByteBuffer buffer = ByteBuffer.allocate(1024);// 3. 从 Channel 读取数据到 Bufferint bytesRead = socketChannel.read(buffer);while (bytesRead > 0) {// 切换到读模式buffer.flip();// 4. 从 Buffer 读取数据while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}// 清空 Buffer,准备下一次读取buffer.clear();bytesRead = socketChannel.read(buffer);}socketChannel.close();}
    }
    

三、 Java IO 与 NIO 的区别

特性Java IO (Blocking IO)Java NIO (Non-blocking IO)
数据传输方式基于流 (Stream)基于通道 (Channel) 和缓冲区 (Buffer)
I/O 模型阻塞式 I/O (Blocking I/O)非阻塞式 I/O (Non-blocking I/O)
选择器没有有 (Selector)
API简单易用相对复杂,需要理解通道、缓冲区、选择器等概念
性能性能较低 (高并发下)性能较高 (高并发下)
线程模型通常使用多线程模型 (每个连接一个线程)通常使用单线程多路复用模型 (一个线程管理多个连接)
适用场景低并发、连接数较少的应用,或者可以接受阻塞的场景高并发、连接数较多的应用,需要高性能和非阻塞的场景,例如网络服务器、聊天服务器等

四、 选择哪种 I/O 模式?

  • 如果你的应用是低并发、连接数较少,并且可以接受阻塞,那么 Java IO 仍然是一个不错的选择,因为它简单易用。
  • 如果你的应用是高并发、连接数较多,并且对性能要求很高,那么应该使用 Java NIO。
  • 一般情况建议直接使用NIO模型,性能更好。

总结

Java IO 和 NIO 都是 Java 平台提供的用于进行输入和输出操作的 API。 Java IO 基于流的模型,使用简单但性能较低; Java NIO 基于通道和缓冲区的模型,提供高性能、非阻塞的 I/O 操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23029.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA使用Maven方式构建SpringBoot项目

1、环境准备 确保你已经安装了以下工具: Java JDK(推荐 JDK 8 或更高版本) IntelliJ IDEA(推荐使用最新版本) 2、创建 Spring Boot 项目 (1) 打开 IntelliJ IDEA。 (2&#xff09…

【Redis原理】底层数据结构 五种数据类型

文章目录 动态字符串SDS(simple dynamic string )SDS结构定义SDS动态扩容 IntSetIntSet 结构定义IntSet的升级 DictDict结构定义Dict的扩容Dict的收缩Dict 的rehash ZipListZipListEntryencoding 编码字符串整数 ZipList的连锁更新问题 QuickListQuickList源码 SkipListRedisOb…

Git Repo下如何制作一个patch文件

Git Repo下如何制作一个patch文件 1. 源由2. 步骤2.1 本地代码差异2.2 添加修改代码2.3 添加未跟踪代码2.4 确认打包文件2.5 输出打包文件2.6 自查打包文件2.7 恢复工作环境 3. 总结 1. 源由 patch分享,更好的差异化比较,减少时间浪费。同时&#xff0c…

跟着李沐老师学习深度学习(十四)

注意力机制(Attention) 引入 心理学角度 动物需要在复杂环境下有效关注值得注意的点心理学框架:人类根据随意线索和不随意线索选择注意力 注意力机制 之前所涉及到的卷积、全连接、池化层都只考虑不随意线索而注意力机制则显示的考虑随意…

STM32的“Unique device ID“能否修改?

STM32F1系列的"Unique device ID"寄存器的地址为0x1FFFF7E8。 这个寄存器是只读的。 "Unique device ID"寄存器位于“System memory”中。“System memory”地址范围为“0x1FFF F000- 0x1FFF F7FF”。 所有STM32 MCU上都存在系统引导加载程序。顾名思义&a…

模型思维 - 领域模型的应用与解析

文章目录 引言模型的核心作用与价值四大模型类型UML建模工具UML类图的核心价值类关系深度剖析企业级建模实践 领域模型(推荐) vs 数据模型(不推荐)区别联系错把领域模型当数据模型错误方案 vs 正确方案对比正确方案的实现1. 数据库…

基于GWO灰狼优化的WSN网络最优节点部署算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 无线传感器网络(Wireless Sensor Network, WSN)由大量分布式传感器节点组成,用于监测物理或环境状况。节点部署是 WSN 的关键问…

产品概念的提出

产品概念的提出 一个产品或者一个产品概念idea是怎么想到的呢?很多情况下它其实来自生活中的一些不爽、不满意、想吐槽,凡是用户抱怨的事情就是用户的强烈刚需需求是我们要去做的事情。当有了一个想法时需要弄清楚一下几个问题: 核心用户事…

3.Docker常用命令

1.Docker启动类命令 1.启动Docker systemctl start docker 2.停止Docker systemctl stop docker 3.重启Docker systemctl restart docker 4.查看Docker状态 systemctl status docker 5.设置开机自启(执行此命令后每次Linux重启后将自启动Docker) systemctl enable do…

交互编程工具之——Jupyter

Jupyter 是什么? Jupyter 是一个开源的交互式编程和数据分析工具,广泛应用于数据科学、机器学习、教育和研究领域。其核心是 Jupyter Notebook(现升级为 JupyterLab),允许用户在一个基于浏览器的界面中编写代码、运行…

使用 AIStor 和 OpenSearch 增强搜索功能

在这篇文章中,我们将探讨搜索,特别是 OpenSearch 如何帮助我们识别模式或查看不断增长的数据中的趋势。例如,如果您正在查看运营数据,如果您的服务似乎是随机的,那么您需要尽可能回溯以识别模式并找出原因。这不仅适用…

java基础学习

java基础 面向对象三大特性 特性:封装、继承、多态; 封装:对抽象的事物抽象化成一个对象,并对其对象的属性私有化,同时提供一些能被外界访问属性的方法; 继承:子类扩展新的数据域或功能&#…

MySQL | MySQL库、表的基本操作01

MySQL库、表的基本操作01 一、库操作1.1 查看数据库1.2 创建数据库1.3 选择数据库1.4 查看创建数据库的SQL语句1.5 修改数据库1.6 删除数据库 二、表操作2.1 创建数据表2.2 查看表2.3 查看表结构2.4 查看创建数据库的SQL语句2.5 修改表2.6 删除表 ⚠️MySQL版本 8.0 一、库操作…

设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件

设备唯一ID获取 支持安卓/iOS/鸿蒙(uni-device-id)UTS插件 介绍 获取设备唯一ID、设备唯一标识,支持安卓(AndroidId/OAID/IMEI/MEID/MacAddress/Serial/UUID/设备基础信息),iOS(Identifier/UUID),鸿蒙&am…

正点原子[第三期]Arm(iMX6U)Linux系统移植和根文件系统构建-5.3 xxx_defconfig过程

前言: 本文是根据哔哩哔哩网站上“arm(iMX6U)Linux系统移植和根文件系统构键篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。 引用: …

力扣热题 100:哈希专题三道题详细解析(JAVA)

文章目录 一、两数之和1. 题目描述2. 示例3. 解题思路4. 代码实现(Java)5. 复杂度分析 二、字母异位词分组1. 题目描述2. 示例3. 解题思路4. 代码实现(Java)5. 复杂度分析 三、最长连续序列1. 题目描述2. 示例3. 解题思路4. 代码实…

嵌入式八股文(五)硬件电路篇

一、名词概念 1. 整流和逆变 (1)整流:整流是将交流电(AC)转变为直流电(DC)。常见的整流电路包括单向整流(二极管)、桥式整流等。 半波整流:只使用交流电的正…

AI2-THOR环境下实现机器人导航、物体定位与抓取

1. 依赖安装 pip install ai2thor pip install numpy pillow opencv-python2. 验证安装 # 运行测试脚本验证安装 test_thor.py from ai2thor.controller import Controller controller Controller(scene"FloorPlan1") controller.step(action"MoveAhead"…

Nginx(详解以及如何使用)

目录 1. 什么是Nginx? 2. 为什么使用nginx? 3. 安装nginx 3.1?安装nginx的依赖插件 3.2 下载nginx ?3.3?创建一个目录作为nginx的安装路径 ?3.4?解压 ?3.5?进入解压后的目录 3.6?指定nginx的安装路径 ?3.7?编译和安装nginx 3.8 启动nginx ?…

【自动化脚本工具】Hammerspoon (Mac)

目录 1. 介绍Hammerspoon 1. 介绍Hammerspoon This is a tool for powerful automation of OS X. At its core, Hammerspoon is just a bridge between the operating system and a Lua scripting engine. What gives Hammerspoon its power is a set of extensions that expo…