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

Java I/O

前言

关于IO, 想必你听过很多中I/O方式, 有的是OS视角的, 有的是JDK本身支持的, 有的是纯实现视角。但是作为一个developer, 我希望你能先搞清楚上下文之后, 再去理解内容, 否则容易抬杠。这个上下文有横向和纵向两个维度。纵向维度包括JDK底层, JDK上层包装库, 开发框架(如Netty)等。 横向的比如在JDK底层实现中支持BIO和NIO, 在JDK上层包装库维度支持BIO、NIO和AIO。开发框架Netty中包含BIO, NIO和OIO。在不同的上下文, 虽然字母缩写是一致的, 但内容却大相径庭。在这里, 我想聊的是JDK中提供的两种最基础的具体实现BIO和NIO。之所以写在这里, 因为这最基础的IO是上层所有IO方式的基础, 而打好基础非常关键。


一、BIO(Blocked I/O)

1. read过程

在这里插入图片描述

  1. 应用获取InputStream, 可能是FileInputStream或者Socket的InputStream;
  2. 应用创建user buffer;
  3. 应用调用InputStream的read(buffer)获取读取的字节数, JVM发起系统调用;
  4. 内核创建Kernel buffer, 读取目标文件描述符并将结果写入Kernel buffer;
  5. 内核将Kerne buffer中读取的数据复制到User buffer中。User buffer填充满或者读取结束后应用侧方法返回;
  6. 应用侧从buffer中获取读取的字节数, 做必要的业务处理;
  7. 重复3-6, 直到读取完成;

2. write过程

在这里插入图片描述

  1. 应用获取OutputStream, 可能是FileOutputStream或者Socket的OutputStream;
  2. 应用创建user buffer;
  3. 应用填充数据到user buffer;
  4. 应用侧调用OutputStream的write(buffer)写出, JVM发起系统调用;
  5. 内核创建Kernel buffer, 并复制User buffer中的数据, 然后将Kernel buffer中的数据写入目标文件描述符, 写入完成后系统调用结束, 应用侧方法调用返回;
  6. 重复3-5直到写入完成

3. 读取文件并发送到网络

在这里插入图片描述
这里我们尝试优化下:

  1. 咱们是读取并转发, 文件从Kernel Buffer复制到User buffer再复制到Kernel buffer, 但实际上应用侧未做任何加工, 因此文件内容不变, 3个buffer的内容是一样的。
  2. 从逻辑的角度, 应用层不需要参与具体IO, 仅仅是告诉内核从哪里Input然后Output到哪里即可。
  3. 从空间占用的角度, 重用一个Kernel Buffer, 将文件内容读取然后发送到Socket。由于复用同一个buffer, 又省去了内存拷贝的开销。
    其实这就是NIO的实现思路。

二、NIO

1.read(get)过程

在这里插入图片描述

  1. 应用获取Channel;
  2. 应用通过channel.map创建内存映射, 将文件的某个部分[offset, length] 和buffer对应起来。此外该buffer对应用和内核均可见;
  3. 应用调用channel.load加载目标内容片段, JVM发起系统调用通知内核加载目标内容。
  4. 内核加载完成后暴露一个内核管理的但是在应用侧又可操作性的buffer, 内核加载过程除了最终暴露的buffer不同其他与BIO过程一致。在load过程中当前线程也是阻塞的。
  5. 后续应用侧可以直接通过应用可见的MappedBuffer读取数据(由于该原因, 图中直接将读取描述为逻辑上与内核无关的操作)
  6. 此外, 对于内存映射文件, 我们不仅可以读取也可以写入, 而后通过force将变更刷新到文件, 相当于BIO中的flush。

2. write(put)过程

在这里插入图片描述

  1. 应用获取Channel;
  2. 应用创建buffer, 该buffer对内核也是可见的;
  3. 应用填充数据到buffer;
  4. 应用调用channel的put(buffer)写出, JVM发起系统调用;
  5. 内核不再创建自己的buffer, 而是直接把已有的buffer中的数据写入文件, 写入完成后系统调用返回;

3. 读取文件并发送到网络

在这里插入图片描述
从图中我们可以看到, 文件数据并没有在应用侧出现, 此外也仅创建了一个Kernel Buffer, 实现了从应用侧仅说明从哪里Input并Output到哪里, 内核完成了整个逻辑过程。

三、两者比较

BIO: 面向Stream, 读写以byte为单位, 需要user buffer和kernel buffer协同(必要时需要两者互相copy)。对内核和JDK版本没要求, 兼容性强, 但效率低。
NIO: 面向Channel, 读写以buffer为单位, user和kernel公用一个buffer(相比于BIO尽可能少copy)。对内核和JDK版本有要求, 兼容性差, 但效率高。


小结

以上就是今天想聊的全部内容, 希望能帮助你对IO的概念,JDK中BIO和NIO的实现基本过程有更深入的理解。

相关文章:

Java I/O

前言 关于IO, 想必你听过很多中I/O方式, 有的是OS视角的, 有的是JDK本身支持的, 有的是纯实现视角。但是作为一个developer, 我希望你能先搞清楚上下文之后, 再去理解内容, 否则容易抬杠。这个上下文有横向和纵向两个维度。纵向维度包括JDK底层, JDK上层包装库, 开发框架(如Ne…...

pytorch学习日记之图片的简单卷积、池化

导入图片并转化为张量 import torch import torch.nn as nn import matplotlib.pyplot as plt import numpy as np from PIL import Image mymi Image.open("pic/123.png") # 读取图像转化为灰度图片转化为numpy数组 myimgray np.array(mymi.convert("L"…...

【java基础】抽象类和抽象方法

文章目录基本介绍抽象类抽象方法使用总结基本介绍 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就…...

RDD的内核调度【博学谷学习记录】

RDD的依赖关系RDD的依赖: 指的一个RDD的形成可能是有一个或者多个RDD得出, 此时这个RDD和之前的RDD之间产生依赖关系在Spark中, RDD之间的依赖关系,主要有二种依赖关系:1- 窄依赖:目的: 为了实现并行计算操作, 并且提高容错的能力指的: 一个RDD上的一个分区的数据, 只能完整的交…...

二叉树——二叉搜索树的最小绝对差

二叉搜索树的最小绝对差 链接 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其数值等于两值之差的绝对值。 示例 1: 输入:root [4,2,6,1,3] 输出:1 示例 2&…...

git的使用(终端输入指令)下

文章目录前言1、git 分支创建分支查看分支切换分支合并分支删除分支2.提交到远程仓库远程提交链接一下自己仓库总结前言 上章链接 :git的使用(终端输入指令)上 我们接着上着来说 上章把 git 的 功能实现了一部分,本章我们接着上文…...

python使用influxdb-client管理InfluxDB的bucket

bucket的概念类似数据库的“库”,同时每个库中的数据都因为存在“时间戳”,每个数据都会有一个对应的时间点 influxdb-client-python官方github页面:https://github.com/influxdata/influxdb-client-python 管理bucket的官方示例&#xff1…...

【c++】模板2—类模板

文章目录类模板语法类模板与函数模板区别类模板中成员函数常见时机类模板对象做函数参数类模板与继承类模板成员函数类外实现类模板分文件编写类模板与友元类模板语法 类模板作用: 建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚…...

基于SpringCloud的可靠消息最终一致性03:项目骨架代码(下)

上一节把整个项目的演示内容、项目结构、POM文件和配置文件都讲完了,接下来继续。 先安装并启动Nacos,然后在其中建立一个名为xiangwang-payment-dev.yaml的配置文件,内容为: # 指定运行环境 spring:autoconfigure:exclude: com.alibaba.druid.spring.boot.autoconfigure.D…...

linux如何彻底的删除文件

一、使用rm命令删除 直接用rm 先用ls -alt看下文件信息及拥有者等 可以看到拥有者是eve用户,所以在eve用户的终端中rm命令即可, 如果是root或者其他,则优先用root或其他账号进行删除 (base) eveEve:~$ ls -alt a.txt -rw-rw-r-- 1 eve eve …...

数据仓库Hive的安装和部署

1)去apache.hive.org官网下载hive 目前hive主要有三大版本,Hive1.x、Hive2.x、Hive3.x Hive1.x已经2年没有更新了,所以这个版本后续基本不会再维护了,不过这个版本已经迭代了很多年了,也是比较稳定的 Hive2.x最近一直…...

Python调用CANoe常见问题

一、Win32com已经安装成功但是在pycharm中提示错误 No module named win32com.clientPyCharm中出现unresolved reference的解决方法 一直提示需要升级pip版本Pywin32已成功安装,但仍提示没有win32com模块...

一起Talk Android吧(第五百零七回:图片滤镜ImageFilterView)

文章目录背景介绍功能介绍图片滤镜图片圆角图片缩放图片旋转图片平移各位看官们大家好,上一回中咱们说的例子是"如何调整组件在约束布局中的角度",这一回中咱们说的例子是" 图片滤镜ImageFilterView"。闲话休提,言归正转&#xff0c…...

Java 解释器和即时解释器(JIT)之间的区别

区别是: 翻译 .class (字节码文件) 的粒度和方式不同 解释器是一个逐条解释并执行字节码指令的组件,每次**只翻译一条**指令并执行,然后再翻译下一条指令。 它的翻译粒度是一条指令,而且是按需翻译&#x…...

Acwing 蓝桥杯 第二章 二分与前缀和

今天来补一下之前没写的总结,题是写完了,但是总结没写感觉没什么好总结的啊,就当打卡了789. 数的范围 - AcWing题库思路:一眼二分,典中典先排个序,再用lower_bound和upper_bound维护相同的数的左界和右界就…...

CSDN原力增长规则解读 实测一个月

CSDN原力越来越难了,当然,这对生态发展来说也是好事。介绍下原力增长有哪些渠道吧。发布原创文章:10分/次,每日上限为15分、2篇回答问题:1分/次,每日上限2分,2回答发动态:1分/次&…...

HDMI协议介绍(三)--InfoFrame

目录 Auxiliary Video information (AVI) InfoFrame AVI InfoFrame包结构 Header Body 举个例子 附录 Audio InfoFrame Audio InfoFrame包结构 Header Body Vendor Specific InfoFrame Vendor Specific InfoFrame包结构 Header Body AVI/AUDIO/VSI Infoframe都…...

【RocketMQ】源码详解:Broker端消息储存流程、消息格式

消息存储流程 入口: org.apache.rocketmq.remoting.netty.NettyRemotingAbstract#processRequestCommand org.apache.rocketmq.broker.processor.SendMessageProcessor#asyncProcessRequest 消息到达broker后会经过netty的解码、消息处理器等,最后根据…...

IoT项目系统架构案例2

项目背景 1.这个项目是对之前的案例的升级改造参考:IoT项目系统架构案例_iot案例_wxgnolux的博客-CSDN博客2.基于方案1的项目实施过程中碰到的问题,对硬件设备标准化的理念及新的功能需求(如根据天气预报温度调水温,APP界面可操作性优化等)•采用目前IoT主流厂商的架…...

Vue echarts封装

做大屏的时候经常会遇到 echarts 展示,下面展示在 Vue2.7 / Vue3 中对 echarts (^5.4.0) 的简单封装。 文章首发于https://blog.fxss.work/vue/echarts封装.html,样例查看 echarts 封装使用 props 说明 参数说明类型可选值默认…...

蓝桥杯入门即劝退(二十二)反转字符(不走寻常路)

欢迎关注点赞评论,共同学习,共同进步! ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法,欢迎订阅专栏共同学习交流! 你的点赞、关注、评论、是我创作的动力! -------希望我的文章…...

数据仓库Hive

HIve介绍 Hive是建立在Hadoop上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载,可以简称为ETL。 Hive 定义了简单的类SQL查询语言,称为HQL,它允许熟悉SQL的用户直接查询Hadoop中的数据&#xf…...

嵌入式 STM32 步进电机驱动,干货满满,建议收藏

目录 步进电机 1、步进电机驱动原理 2、步进电机驱动 3、步进电机应用 1、第一步:初始化IO口 2、设置行进方式 四、源码 步进电机 步进电机被广泛应用于ATM机、喷绘机、刻字机、写真机、喷涂设备、医疗仪器及设备、计算机外设及海量存储设备、精密仪器、工业…...

详讲函数.2.

目录 5. 函数的嵌套调用和链式访问 5.1 嵌套调用 5.2 链式访问 小结: 6. 函数的声明和定义 6.1 函数的声明: 6.2 函数的定义: 5. 函数的嵌套调用和链式访问 函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的…...

行测-判断推理-图形推理-位置规律-旋转、翻转

短指针每次逆时针旋转60(排除法选C走人)长指针每次顺时针旋转120选C左上菱形每次顺时针旋转90(排除C D)右上每次旋转180(选B走人)左下每次保持不变右下每次逆时针旋转90选B左上和右上为左右翻转&#xff0c…...

linux shell 入门学习笔记15 shell 条件测试

概念 shell的条件测试目的是得出真和假。 shell 提供的条件测试语法 test 命令 [] 中括号命令 语法*: test条件测试 test命令用来评估一个表达式,他的结果是真,还是假,如果条件为真,那么命令执行状态结果就为0&…...

Apollo(阿波罗)分布式配置安装详解

Apollo(阿波罗) Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性&#…...

Vue3之组件

何为组件 组件化的概念已经提出了很多年了,但是何为组件呢?组件有啥优势?本文将会做出解答,首先我们需要弄清楚何为组件。在VUE的官网中的解释是: 组件允许我们将 UI 划分为独立的、可重用的部分,并且可以对…...

【网络】套接字 -- UDP

🥁作者: 华丞臧. 📕​​​​专栏:【网络】 各位读者老爷如果觉得博主写的不错,请诸位多多支持(点赞收藏关注)。如果有错误的地方,欢迎在评论区指出。 推荐一款刷题网站 👉 LeetCode刷题网站 文章…...

Lambda原理及应用

Lambda原理及应用 Lambda介绍 Lambda 是 JDK8 以后版本推出的一个新特性,也是一个重要的版本更新,利用 Lambda 可以简化内部类,可以更方便的进行集合的运算,让你的代码看起来更加简洁,也能提升代码的运行效率。 Lambda语法 非…...

安丘网站建设开发/seo外包收费

概要 本分步指南介绍了如何在 Windows XP 中使用 Windows 资源管理器命令行参数。 更多信息 使用命令行参数,您既可以自定义 Windows 资源管理器启动时使用的默认视图,也可以指定在从命令提示符启动时所看到的视图。 您可以在 Explorer.exe 命令中使…...

黑龙江省住房和建设厅网站/群发软件

我想说: 2017年入CSDN来,从2019年开始坚持写一些自己的平时学习心得、技术要点、前端技术、脱坑指南等文章 谢谢各位的支持,共前行 截至到专家认证当天已经书写 截至2021年 3月11日 14:39...

j2ee网站开发/网站推广四个阶段

第一种  1、windows下进入CMD启动2、在命令行中输入Tomcat安装的磁盘:E:3、进入Tomcat的主安装目录:cd Tomcat4、进入bin文件夹:cd bin5、查看该文件夹下边的文件目录:dir6、启动startup.bat 命令行中输入:startup.ba…...

2018做网站前景好么/正规教育培训机构

思路:回顾了下网络流中最简单暴力的一个方法:Ford-Fulkerson算法。 本文不再讲解具体算法原理,直接上代码(我这里采用的邻接矩阵,希望各位不要学我,还是用邻接表比较稳哦): #inclu…...

wordpress 链接打不开/关键词com

也许您正在为架设服务器的烦琐步骤而苦恼,也许您正为配置PHP,asp环境感到困惑。那么现在,中电云集请您放心,您的这些困惑苦恼,我们为您解决。为了服务器爱好者和使用者能更简单、快捷的架设自己的服务器,我们推出最新产品---china…...

网站设计论文前言怎么写/世界杯32强排名

public class Test { //外部类public static void main(String[] args) {EnclosedClazz enclosedClazz new EnclosedClazz();//这里返回的实际是一个InnerSon对象Father f enclosedClazz.test();//定义在test()里的内部类对象is,存活到现在//父类引用指向子类对…...