Java NIO 深度解析:构建高效的 I/O 操作
在 Java 编程领域,I/O 操作一直是至关重要的部分,它直接影响着应用程序的性能和响应能力。Java NIO(New I/O)作为传统 I/O 的增强版本,为处理大量并发连接和高效的数据传输提供了更强大的工具和机制。本文将深入探讨 Java NIO 的核心概念、关键组件以及如何运用它来构建高性能的 I/O 应用程序。
一、Java NIO 概述
Java NIO 是在 Java 1.4 中引入的一套全新的 I/O API,它与传统的 Java I/O(基于流的 I/O)有所不同。NIO 采用了基于通道(Channel)和缓冲区(Buffer)的非阻塞式 I/O 模型,这种模型能够在处理大量并发连接时表现出更好的性能和可扩展性。
传统的 I/O 操作在进行数据读取或写入时,往往会阻塞当前线程,直到操作完成。这在处理高并发场景时,会导致大量线程处于等待状态,浪费系统资源并降低应用程序的吞吐量。而 Java NIO 的非阻塞特性允许线程在等待 I/O 操作完成的过程中执行其他任务,从而提高了系统的资源利用率和响应速度。
二、核心组件
1. 通道(Channel)
通道是 NIO 中数据传输的载体,类似于传统 I/O 中的流,但具有更高的抽象层次和更多的功能。通道可以用于读取和写入数据,并且支持双向操作。常见的通道类型包括:
- FileChannel:用于文件的读写操作。可以从文件中读取数据到缓冲区,或者将缓冲区中的数据写入到文件。
- SocketChannel:用于网络套接字的读写操作。可以与远程服务器建立连接,并进行数据传输。
- ServerSocketChannel:用于监听网络端口,接受客户端的连接请求,并创建对应的
SocketChannel
实例。
例如,使用 FileChannel
读取文件的示例代码如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;public class FileChannelExample {public static void main(String[] args) {try {File file = new File("test.txt");FileInputStream fis = new FileInputStream(file);FileChannel channel = fis.getChannel();ByteBuffer buffer = ByteBuffer.allocate((int) file.length());channel.read(buffer);buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}channel.close();fis.close();} catch (IOException e) {e.printStackTrace();}}
}
在上述示例中,首先通过 FileInputStream
获取对应的 FileChannel
,然后创建一个 ByteBuffer
缓冲区,将文件数据读取到缓冲区中,并最后将缓冲区中的数据打印出来。
2. 缓冲区(Buffer)
缓冲区是用于存储数据的容器,在 NIO 中所有的数据读写操作都是通过缓冲区来完成的。缓冲区具有以下几个重要属性:
- 容量(Capacity):缓冲区能够容纳的最大数据量。
- 位置(Position):当前缓冲区中数据的读写位置。
- 限制(Limit):缓冲区中可操作数据的边界。
常见的缓冲区类型有 ByteBuffer
、CharBuffer
、IntBuffer
等,分别用于处理不同类型的数据。例如,ByteBuffer
可以用于存储字节数据,适用于大多数通用的 I/O 操作。
以下是一个简单的 ByteBuffer
使用示例,展示了数据的写入和读取过程:
import java.nio.ByteBuffer;public class ByteBufferExample {public static void main(String[] args) {ByteBuffer buffer = ByteBuffer.allocate(1024);// 写入数据到缓冲区buffer.put((byte) 'H');buffer.put((byte) 'e');buffer.put((byte) 'l');buffer.put((byte) 'l');buffer.put((byte) 'o');// 切换缓冲区为读模式buffer.flip();// 从缓冲区读取数据while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}}
}
在这个示例中,首先分配了一个容量为 1024 的 ByteBuffer
,然后向其中写入了字符串 "Hello" 的字节数据,接着通过 flip
方法切换缓冲区为读模式,最后循环读取并打印缓冲区中的数据。
3. 选择器(Selector)
选择器是 NIO 实现非阻塞 I/O 的关键组件。它可以同时监听多个通道的事件,例如连接就绪、读就绪、写就绪等事件。通过使用选择器,单个线程可以管理多个通道的 I/O 操作,从而实现高效的并发处理。
以下是一个使用 Selector
实现简单的网络服务器示例,该服务器可以同时处理多个客户端连接:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;public class NIOServer {public static void main(String[] args) throws IOException {// 创建 ServerSocketChannelServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.bind(new InetSocketAddress(8888));serverSocketChannel.configureBlocking(false);// 创建 SelectorSelector selector = Selector.open();// 将 ServerSocketChannel 注册到 Selector 上,监听连接事件serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 阻塞等待事件发生selector.select();// 获取发生事件的 SelectionKey 集合Set<SelectionKey> selectionKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();if (key.isAcceptable()) {// 处理连接事件ServerSocketChannel server = (ServerSocketChannel) key.channel();SocketChannel socketChannel = server.accept();socketChannel.configureBlocking(false);// 将新连接的 SocketChannel 注册到 Selector 上,监听读事件socketChannel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {// 处理读事件SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int numRead = socketChannel.read(buffer);if (numRead == -1) {// 客户端关闭连接socketChannel.close();} else {buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);System.out.println("Received from client: " + new String(data));// 处理完数据后,将数据写回客户端buffer.flip();socketChannel.write(buffer);}}}}}
}
在这个示例中,首先创建了 ServerSocketChannel
并绑定到指定端口,将其设置为非阻塞模式后注册到 Selector
上监听连接事件。然后进入一个循环,通过 selector.select()
阻塞等待事件发生。当有事件发生时,遍历 selectedKeys
集合,根据事件类型分别处理连接事件和读事件。对于读事件,从客户端读取数据并打印,然后将数据写回客户端。
三、NIO 的优势与应用场景
1. 优势
- 非阻塞 I/O:减少线程阻塞等待时间,提高系统资源利用率和并发处理能力。
- 缓冲区操作:直接对缓冲区进行数据处理,减少数据复制次数,提高数据传输效率。
- 多路复用:通过选择器实现单个线程管理多个通道,降低系统开销,适用于高并发网络应用。
2. 应用场景
- 网络编程:如高性能的 Web 服务器、网络代理服务器、即时通讯软件等,需要处理大量并发连接的场景。
- 文件处理:对于大文件的读写操作,NIO 能够提供更高效的方式,例如文件上传下载、文件系统监控等。
四、总结
Java NIO 通过引入通道、缓冲区和选择器等核心组件,为 Java 开发者提供了一种高效、灵活的 I/O 处理方式。它在处理高并发和大数据量的 I/O 操作时表现出色,能够显著提升应用程序的性能和可扩展性。理解和掌握 Java NIO 的原理和使用方法,对于开发高性能的网络应用和处理大规模数据的程序具有重要意义。希望本文能够帮助读者深入了解 Java NIO,并在实际项目中充分发挥其优势,构建出更加健壮和高效的 Java 应用程序。
相关文章:
Java NIO 深度解析:构建高效的 I/O 操作
在 Java 编程领域,I/O 操作一直是至关重要的部分,它直接影响着应用程序的性能和响应能力。Java NIO(New I/O)作为传统 I/O 的增强版本,为处理大量并发连接和高效的数据传输提供了更强大的工具和机制。本文将深入探讨 J…...
总结拓展十六:特殊采购业务——VMI采购模式
1、VMI的定义 VMI采购模式(Vendor Managed Inventory)是一种合作性策略,旨在通过供应商管理库存,使供应链中的企业和供应商双方都能获得最低成本。在这种模式下,供应商根据共享的用户企业库存和实际耗用数据&#x…...
vue2 + iview(view-design) 中封装使用 vxe-table 处理表格渲染大量数据卡顿现象
今天遇到需求,iview组件分页每页100页时候页面卡顿现象严重,改造为使用vxe-table cell-mouseenter"handleCellMouseEnter" cell-mouseleave"handleCellMouseLeave" 这两个用来处理vxe-table 内容过多鼠标悬浮上去滚动 tooltip直接…...
初学者指南:知识库问答(KBQA)多跳路径的核心与应用
初学者指南:知识库问答(KBQA)多跳路径的核心与应用 知识库问答(Knowledge Base Question Answering, KBQA)旨在利用结构化知识库(如Wikidata、Freebase)回答自然语言问题。在实际应用中&#x…...
创建springboot+vue项目相关配置问题
安装并配置jdk23 在官网下载jdk Java Downloads | Oracle 中国 下载完成后双击即可安装。 安装完成后配置环境变量 此电脑->右键->属性->高级系统设置 然后一直点击确定即可。 键盘上win r java -version 可以验证是否配置成功 下载并配置maven 在官网下…...
基于AOA算术优化的KNN数据聚类算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于AOA算术优化的KNN数据聚类算法matlab仿真。通过AOA优化算法,搜索最优的几个特征数据,进行KNN聚类,同时对比不同个数特征下…...
【机器学习】在泊松分布中,当λ值较大时,其近似正态分布的误差如何评估?
在泊松分布中,当参数 λ 较大时,其近似正态分布的有效性可以通过 中心极限定理 和误差分析来理解和评估。以下内容结合理论推导和实际案例展开说明: 1. 泊松分布的定义 泊松分布是用于建模单位时间或单位空间内随机事件发生次数的概率分布&a…...
ABAP开发-面向对象开发_2
系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言接口和类1、首先创建一个接口2、在创建的接口的基础上创建一个类PERSON3、创建子类STUDENT4、创建子类TEACHER5、SE38使用创建的类 总结 前言 接口和类 全局类 SE24 创建一个接口-》创建一个实现接口的类-》再创建两个…...
微信小程序-prettier 格式化
一.安装prettier插件 二.配置开发者工具的设置 配置如下代码在setting.json里: "editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml"…...
241118学习日志——[CSDIY] [ByteDance] 后端训练营 [06]
CSDIY:这是一个非科班学生的努力之路,从今天开始这个系列会长期更新,(最好做到日更),我会慢慢把自己目前对CS的努力逐一上传,帮助那些和我一样有着梦想的玩家取得胜利!!&…...
Android WMS概览
WMS(WindowManagerService)是 Android 系统的核心服务,负责管理应用和系统的窗口,包括窗口的创建、销毁、布局、层级管理、输入事件分发以及动画显示等。它通过协调 InputManager 和 SurfaceFlinger 实现触摸事件处理和窗口渲染&a…...
新一代API开发工具,让API调试更快 更简单
新一代API开发工具 代理调试 请求测试一站式解决方案 Reqable Fiddler Charles Postman, 让API调试更快 🚀 更简单 👌 直接上下载地址 根据系统,下载对应的版本即可 https://reqable.com/zh-CN/download/...
友元类和友元函数
友元函数的定义: 友元函数是在类定义中被声明为 “朋友” 的非成员函数。它可以访问类的私有成员和保护成员(变量和方法),就好像它是类的成员函数一样。友元函数的声明以friend关键字开头,在类的内部进行声明,但它的定义在类的外部ÿ…...
Sulfo-Cy5-Iodoacetamide能够发出明亮的荧光信号,使得生物样本的精细结构得以清晰呈现
一、基本信息 英文名称:Sulfo-Cy5-Iodoacetamide,Sulfo-Cyanine5-Iodoacetamide,Sulfo Cy5 IA 中文名称:磺酸Cy5碘乙酰胺 分子式:C36H44IKN4O8S2 分子量:890.89 纯度:≥95% 外观ÿ…...
Python中的TCP
文章目录 一. 计算机网络1. 网络的概念2. IP地址① IP地址的概念② IP地址的表现形式③ IP地址的作用④ 网络查询命令Ⅰ. ifconfig/ipconfigⅡ. ping 3. 端口和端口号的概念(计算机通信原理)① 端口的概念② 端口号的概念 4. socket套接字① socket概念② socket使用场景 二. T…...
CSS(8)高级技巧:精灵图,css三角,用户界面,vertical-align属性应用
一.精灵图 通过css中的background-position属性,将多张图合成为一张图 二.css三角 在网页中,我们可以添加css属性获得三角图标 solid:实心,边框的实心 transparent:透明,图中代码表示只有左边粉色,其余地方为透明 三ÿ…...
Flink新版Source接口源码解析
目录 1. 前言 2. Source解析 2.1 Source类图 2.2 接口和方法说明 2.2.1 Source,> 3. SplitEnumerator解析 3.1 SplitEnumetator类图 3.2 类和方法说明 3.2.1 SplitEnumerator 3.2.2 SimpleVersionedSerializer 4. SourceReader解析 4.1 SourceReader类图 4.2 类…...
SLM561A系列60V10-50mA单通道线性恒流LED驱动芯片,为汽车照明、景观照明助力
SLM561A系列选型参考: SLM561A10ae-7G SOD123 SLM561A15ae-7G SOD123 SLM561A20ae-7G SOD123 SLM561A25ae-7G SOD123 SLM561A30ae-7G SOD123 SLM561A35ae-7G SOD123 SLM561A40ae-7G SOD123 SLM561A45ae-7G SOD123 SLM561A50ae-7G SOD123 S…...
一次失败的wxpython安装macOS M1
WARNING: The scripts libdoc, rebot and robot are installed in /Users/用户名/Library/Python/3.8/bin which is not on PATH. 背景:想在macos安装Robot Framework ,显示pip3不是最新,更新pip3后显示不在PATH上 参看博主文章末尾 MAC系统…...
【大数据技术基础 | 实验十一】Hive实验:新建Hive表
文章目录 一、实验目的二、实验要求三、实验原理四、实验环境五、实验内容和步骤(一)启动Hive(二)创建表(三)显示表(四)显示表列(五)更改表(六&am…...
【yarn】yarn rest api每日job数量分析
一、说明 # 无法制定时间范围!!! yarn application -list 官方文档 rest返回内容(官网案例): {app":{"id":"application_1324057493980_0001","user":"user1&q…...
蓝桥杯单片机第十一届省赛(第一场)
主函数代码 #include<iic.h> #include<intrins.h>sfr P40xc0; sbit R3P3^2; sbit R4P3^3; sbit C4P3^4; sbit C3P3^5;unsigned char code led_nodot[]{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char code led_dot[]{0x40,0x79,0x24,0x30,0x…...
hive复杂数据类型Array Map Struct 炸裂函数explode
1、Array的使用 create table tableName( ...... colName array<基本类型> ...... ) 说明:下标从0开始,越界不报错,以null代替 arr1.txtzhangsan 78,89,92,96 lisi 67,75,83,94 王五 23,12 新建表: create table arr1(n…...
FIFO架构专题-FIFO是什么
目录 简介: FIFO参数: 1.宽度WIDTH(一次位数) 2.深度DEEPTH(存多少次) FIFO的分类: 同步FIFO 异步FIFO 读写位宽不同的FIFO FIFO信号介绍 写时钟 写数据 写使能 读时钟 读数据 读…...
Pythony——多线程简单爬虫实现
简单爬虫实现 import requests from bs4 import BeautifulSoup# 生成要爬取的网页地址列表,这里是博客园的分页地址,从第1页到第50页 urls [f"https://www.cnblogs.com/#p{i}" for i in range(1, 50 1)]# 生产者函数——负责下载网页内容 d…...
如何修改 a 链接的样式
在CSS中,你可以使用选择器来针对HTML中的特定元素(例如<a>标签,也就是链接)进行修改样式。以下是一些常见的修改<a>链接样式的方法: 移除下划线: a { text-decoration: none; } 修改链接的…...
第6章 详细设计-6.5 软硬件接口文档设计
6.5 软硬件接口文档设计 一般的产品都包含硬件和软件两部分,产品设计阶段需要确保硬件开发人员和软件开发的沟通准确、高效。所以需要一份书面的文档来承载软件和硬件之间的沟通细节。以下面的细水雾除尘设备为例进行讲解,涉及软件和硬件的接口ÿ…...
【pyspark学习从入门到精通14】MLlib_1
目录 包的概览 加载和转换数据 在前文中,我们学习了如何为建模准备数据。在本文中,我们将实际使用这些知识,使用 PySpark 的 MLlib 包构建一个分类模型。 MLlib 代表机器学习库。尽管 MLlib 现在处于维护模式,即它不再积极开发…...
C++全局构造和初始化
片段摘自程序员的自我修养—链接、装载与库.pdf 11.4 程序在进入main之前,需要对全局对象进行构造初始化。 glibc全局对象进行构造初始化 gibc启动程序时会经过.init段,退出程序时会经过.finit段。这两个段中的代码最终拼接成_init()和_finit(),这两个…...
安全见闻-泷羽sec课程笔记
编程语言 C语言:一种通用的、面向过程的编程语言,广泛应用于系统软件和嵌入式开发。 C:在C语言基础上发展而来,支持面向对象编程,常用于尊戏开发、高性能计算等领域。 Java:一种广泛使用的面问对象编程语言,具有跨平台…...
网站建设需要哪些岗位/seo搜索方法
计算机上有一些唯一的标志符,比如网卡MAC地址,CPU序列号,硬盘序列等。有时候为了开发授权码或者注册码,需要根据具体计算机进行授权,这是就需要获取这些唯一标识信息了。 首先,是网卡MAC地址的获取。网卡其…...
阿里云怎么wordpress/河南今日头条新闻最新
1. 系统信息 1.1 操作系统类型 查看操作系统类型命令为 uname 例: [roothost-134 ~]# uname Linux定义变量 os_type$(uname)1.2 操作系统版本号 查看操作系统版本号命令为 cat /etc/redhat-release 例: [roothost-134 ~]# cat /etc/redhat-release…...
好的兼职做调查网站/百度浏览器app
在windos 的cmd下安装mysql 在mysql的bin目录下面执行: mysqld --install 报错: 信息如下一: Install/Remove of the Service Denied 解决办法: 打开cmd.exe程序的时候选择“用管理员身份打开”。 错误信息二: …...
交易网站开发/2024年3月新冠肺炎
1、从网站可以正常使用的时间上来说如果用不备案的国外空间,申请域名购买空间后网站是直接可以打开访问的,如果备案,工信部公布的审核时间是20个工作日,也就是说除去周六周日要进一个月备案才能审批下来,之后才能正常访…...
wordpress 做cms/网站推广开户
使用Chrome自带的Javascript调试工具。 1. 将写好的Javascript代码用chrome打开 在页面,单击右键,并且选择“审查元素” 弹出窗体,如图所示: 2. 然后,点击“Resources”标签,如图所示: 3. 然…...
wordpress和wiki/百度快速排名优化服务
Matlab Matlab WdbN N1,2,3,...,50 别可以 ind2depo 将索引结点形式转化成深度—位置结点形式 * intwave 积分小波数 isnode 判断结点是否存在 Matlab......Matlab 之小波滤波函数 南京理工大学仪器科学与技术专业 谭彩铭 2010-3-20 1 ...N must be a strictly positive intege…...