IO-概述

news2024/11/17 13:31:37

概述

​ IO是Input(输入)和Output(输出)的首字母缩写。
​ I(输入Input):指向Java程序中输入数据,即Java程序从外部获取数据
​ O(输出Output):指的是Java程序向外部输出数据,即Java程序向外部发送数据

​ 流:**在Java程序和外部之间,数据像水流一样按照顺序传输。Java中,流有两种形式,字节流和字符流。

​ 外部(也就是数据源)包括:源设备 和 目标设备
​ 源设备:Java程序使用Input(输入)获取数据的来源
​ 目标设备:Java程序使用Output(输出)发送数据的目的地

作用

Java IO用在Java程序和外部进行数据交互,Java程序运行在内存中,要与外部(如:磁盘、网络、数据库等)地方交互数据则需要使用Java IO
​ 比如:在本地磁盘的某个txt文件上读写运行日志、读写MySQL数据库的内容等。

IO分类

​ Java中,**流有两种形式,字节流和字符流。**所对照的四大抽象类分别为:InputStream、OutputStream 和 Reader、Writer。这四个抽象类一般不进行实例化,使用的时候一般通过它们的子类调用继承自父类的方法。IO完成之后,一般要使用close方法,否则会造成不必要的资源浪费和卡顿麻烦。

字节流和字符流的区别

  • 字节流读取单个字节,字符流读取单个字符(一个字符根据编码的不同,对应的字节也不同,如 UTF-8 编码中文汉字是 3 个字节,GBK编码中文汉字是 2 个字节。)
  • 字节流用来处理二进制文件(图片、MP3、视频文件)字符流用来处理文本文件(可以看做是特殊的二进制文件,使用了某种编码,人可以阅读)。

字节流

字节流下有两大抽象类:InputStream、OutputStream。
在这里插入图片描述

字符流

字符流下有两大抽象类:Reader、Writer
在这里插入图片描述

字节流转字符流

编码就是把字符转换为字节,而解码是把字节重新组合成字符。

如果编码和解码过程使用不同的编码方式那么就出现了乱码。

  • GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节;
  • UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节;
  • UTF-16be 编码中,中文字符和英文字符都占 2 个字节。

​ Java 使用双字节编码 UTF-16be,是指的char 这种类型使用 UTF-16be 进行编码。char 类型占 16 位,也就是两个字节。UTF-16be 中的 be 指的是 Big Endian,也就是大端。相应地也有 UTF-16le,le 指的是 Little Endian,也就是小端。

数据来源/操作对象进行划分

文件(file)

FileInputStream、FileOutputStream、FileReader、FileWriter

数组

  • 字节数组(byte[]): ByteArrayInputStream、ByteArrayOutputStream
  • 字符数组(char[]): CharArrayReader、CharArrayWriter

管道通讯

PipedInputStream、PipedOutputStream、PipedReader、PipedWriter

​ **操作有原子性,可以实现普通文件的操作原子性。可以以流方式操作的文件,具备缓冲特性。遵循先入先出原则。**在Linux系统中,管道是进程间通信的媒介。管道是内核里面的一串缓存,通过管道的文件描述符可以找到它,所以拿到管道的文件描述符的进程之间就可以通信

基本数据类型

DataInputStream、DataOutputStream 基本数据类型的字节输入输出流。

缓冲操作(按照缓冲处理数据)

BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

打印(按照格式化输出)

PrintStream、PrintWriter

对象序列化/反序列化

ObjectInputStream、ObjectOutputStream

日常使用直接实现序列化接口SerializableserialVersionUID 的字段。这是一个版本控制机制,用于在反序列化过程中检查序列化的类和反序列化的类是否兼容。在生产环境中,为每个可序列化的类分配唯一的 serialVersionUID 是一个好习惯。

实例对象为什么要实现序列化接口

序列化就是对实例对象的状态(State 对象属性而不包括对象方法)进行通用编码(如格式化的字节码)并保存,以保证对象的完整性和可传递性

简而言之:序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象,尤其是避免中文乱码问题

转换(字节字符转换流)

InputStreamReader、OutputStreamWriter 把字节流转换成字符流.

注意:

​ **当不涉及到网路传入或其他场景时,可以通过字符流中的另外两个子类,FileReader和FileWriter,直接把数据读成字符流;**因为使用字节流,操作中文的话,会出现乱码问题。

IO设计模式

装饰器模式

装饰器模式就是不改变接口,但加入责任。

场景:广泛应用于 FilterInputStream、FilterOutputStream、FilterReader 和 FilterWriter 这些类。这些类充当装饰器角色,可以包装其他流对象并为它们提供额外的功能,如缓冲、数据处理等

适配器模式

将一个接口转换为另一个接口

场景:字节流转字符流

观察者模式

当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。

场景:信号渠道I/O类似于观察者模式,内核就是个观察者,信号回调就是个异步通知,用户进程发起I/O操作时,通过系统调用sigaction函数,在对于的套接字注册一个信号回调,此时不阻塞用户进程,当内核数据准备就绪时,内核会为该进程生成SIGIO信号,通过信号回调通知进行I/O操作。

IO常见操作类

Java 的 I/O 大概可以分成以下几类:

  • 磁盘操作: File
  • 字节操作: InputStream 和 OutputStream
  • 字符操作: Reader 和 Writer
  • 对象操作: Serializable
  • 网络操作: Socket

File相关

File 类可以用于表示文件和目录的信息,但是它不表示文件的内容

序列化 & Serializable & transient

序列化就是将一个对象转换成字节序列,方便存储和传输。

  • 序列化: ObjectOutputStream.writeObject()
  • 反序列化: ObjectInputStream.readObject()

​ 不会对静态变量进行序列化,因为序列化只是保存对象的状态静态变量属于类的状态。

Serializable

序列化的类需要实现 Serializable 接口,它只是一个标准,但是如果不去实现它的话而进行序列化,会抛出异常。

transient

transient 关键字可以使一些属性不会被序列化。

​ ArrayList 中存储数据的数组 elementData 是用 transient 修饰的,因为数组是动态扩展的,是按照1.5倍扩展,有部分空间并未使用,因此就不需要所有的内容都被序列化。通过重写序列化和反序列化方法,使得可以只序列化数组中有内容的那部分数据

Java 中的网络支持:

  • InetAddress: 用于表示网络上的硬件资源,即 IP 地址;
  • URL: 统一资源定位符;
  • Sockets: 使用 TCP 协议实现网络通信;
  • Datagram: 使用 UDP 协议实现网络通信。

InetAddress

没有公有的构造函数,只能通过静态方法来创建实例。

URL

可以直接从 URL 中读取字节流数据。

Sockets

  • ServerSocket: 服务器端类
  • Socket: 客户端类
  • 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。

Datagram

  • DatagramSocket: 通信类
  • DatagramPacket: 数据包类

IO模型

介绍

一个输入操作通常包括两个阶段:

  • 等待数据准备好
  • 从内核向进程复制数据

​ 对于一个套接字上的输入操作,第一步通常涉及等待数据从网络中到达当所等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用进程缓冲区。
​ IO模型一共有5种:同步阻塞I/O、同步非阻塞I/O,I/O多路复用、信号驱动I/O和异步I/O。这也是常用的5种IO模型。

​ Java中的NIO是在Java 1.4引入,对应java.io包,提供了Channel,Selector,Buffer等抽象。NIO中的N理解为Non-blocking,不单纯是New,它支持面向缓冲,基于通道的I/O操作方法,对于高负载、高并发的网络与应用,应使用NIO。Java中的NIO可以看作为是I/O多路由复用。也有人认为,Java中的NIO属于同步非阻塞IO模型

Unix 下有五种 I/O 模型:

  • 阻塞式 I/O
  • 非阻塞式 I/O
  • I/O 复用(select 和 poll)
  • 信号驱动式 I/O(SIGIO)
  • 异步 I/O(AIO)

阻塞式 I/O

​ **应用进程被阻塞,直到数据复制到应用进程缓冲区中才返回。**在阻塞的过程中,其它程序还可以执行,不消耗 CPU 时间,这种模型的执行效率会比较高。

非阻塞式 I/O

​ 应用进程执行系统调用之后,内核返回一个错误码。应用进程可以继续执行,但是需要不断的执行系统调用来获知 I/O 是否完成,这种方式称为轮询(polling)。由于 CPU 要处理更多的系统调用,因此这种模型是比较低效的。

I/O 复用

​ 使用 select 或者 poll 等待数据,并且可以等待多个套接字中的任何一个变为可读。这一过程会被阻塞,当某一个套接字可读时返回;再使用 recvfrom 把数据从内核复制到进程中。
Linux下目前暂不支持异步IO技术,所以使用的是epoll(多路复用IO技术)对异步IO进行模拟。

​ 它可以让单个进程具有处理多个 I/O 事件的能力。又被称为 Event Driven I/O,即事件驱动 I/O。其中epoll 的描述符事件有两种触发模式: LT(level trigger)和 ET(edge trigger)

1. LT 模式

LT模式是会有两次通知。当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件,下次调用 epoll_wait() 会再次通知进程。是默认的一种模式,并且同时支持 Blocking 和 No-Blocking。

2. ET 模式

ET模式是通知之后进程必须立即处理事件,下次再调用 epoll_wait() 时不会再得到事件到达的通知。

信号驱动 I/O

​ 应用进程使用 sigaction 系统调用,内核立即返回,应用进程才可以继续执行,也就是说等待数据阶段应用进程是非阻塞的内核在数据到达时向应用进程发送 SIGIO 信号,应用进程收到之后在信号处理程序中调用 recvfrom 将数据从内核复制到应用进程中

相比于非阻塞式 I/O 的轮询方式,信号驱动 I/O 的 CPU 利用率更高

异步 I/O

进行 aio_read 系统调用会立即返回,应用进程继续执行,不会被阻塞,内核会在所有操作完成之后向应用进程发送信号。

​ 异步 I/O 与信号驱动 I/O 的区别在于,异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O


同步 I/O 与异步 I/O

  • 同步 I/O: 应用进程在调用 recvfrom 操作时会阻塞
  • 异步 I/O: 不会阻塞

阻塞式 I/O、非阻塞式 I/O、I/O 复用和信号驱动 I/O 都是同步 I/O,虽然非阻塞式 I/O 和信号驱动 I/O 在等待数据阶段不会阻塞,但是在之后的将数据从内核复制到应用进程这个操作会阻塞

总结

在 Java I/O 编程中,选择合适的流非常重要。

数据类型:

​ 首先确定要处理的数据类型。如果要处理的是字节数据(如图像、音频、视频等),则选择字节流(如 FileInputStream、FileOutputStream 等)。如果要处理的是字符数据(如文本文件),则选择字符流(如 FileReader、FileWriter 等)。

输入还是输出:

​ 确定是需要读取数据(输入)还是写入数据(输出)。对于输入操作,选择输入流(如 FileInputStream、FileReader 等),对于输出操作,选择输出流(如 FileOutputStream、FileWriter 等)。

缓冲还是非缓冲:

​ 考虑是否需要缓冲来提高 I/O 性能。对于大量连续的 I/O 操作,使用缓冲流(如 BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter 等)通常会提高性能。缓冲流在内部使用缓冲区,可以减少实际的磁盘或网络访问次数,从而提高效率。

数据处理需求:

​ 根据需要处理的数据类型,选择合适的流。例如,如果需要处理基本数据类型(如整数、浮点数等),可以使用 DataInputStream 和 DataOutputStream。如果需要处理对象序列化,可以使用 ObjectInputStream 和 ObjectOutputStream。

特定场景:

​ 针对特定场景选择合适的流。例如,在处理多个文件合并时,可以使用 SequenceInputStream;在处理线程间通信时,可以使用管道流,如 PipedInputStream 和 PipedOutputStream,或 PipedReader 和 PipedWriter。

以下是一些常见场景及建议使用的流:

处理文本文件:

使用 FileReader、FileWriter、BufferedReader 和 BufferedWriter

处理二进制文件:

使用 FileInputStream、FileOutputStream、BufferedInputStream 和 BufferedOutputStream

读取或写入基本数据类型:

使用 DataInputStream 和 DataOutputStream

对象序列化和反序列化:

使用 ObjectInputStream 和 ObjectOutputStream

合并多个文件:

使用 SequenceInputStream

线程间通信(管道通讯):

使用 PipedInputStream 和 PipedOutputStream,或 PipedReader 和 PipedWriter

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c盘游戏怎么转移到d盘?无需重新安装

概述:游戏占用的容量一般很大,如果都存在C盘中,可能会导致C盘空间不足,这时候我们可以考虑迁移游戏到其他盘。c盘游戏怎么转移到d盘?本指南详细讲解。 一、为什么需要将游戏移动到其他盘 现在很多游戏玩家&#xff0c…

基于结构化跨模态表示一致性的临床辅助结直肠息肉识别

文章目录 Toward Clinically Assisted Colorectal Polyp Recognition via Structured Cross-Modal Representation Consistency摘要本文方法Shared Transformer BlockCross-Modal Global AlignmentSpatial Attention Module 实验结果 Toward Clinically Assisted Colorectal Po…

Liunx下pip3换源(最详细)

在使用python时我们经常会安装各种包,我们一般安装的方式都是pip3 install xx模块,但是pip3默认源https://pypi.org/安装的过程非常慢,可能都是几k几k的,有时安装这安装着,直接error了,还有一种情况是直接飘…

BSR:Block compressed Sparse Row matrix format

BSR块压缩存储是CSR行压缩存储的升级变形;可以降低图数据存储空间。 有以下图的矩阵表示: 一、CSR表示 rowIndex [0 4 8 10 12 16 20] columns [0 1 2 3 | 0 1 2 3 | 2 3 | 2 3 | 2 3 4 5 | 2 3 4 5] values …

倒计时 1 天:Tapdata LDP V3 发布会预告,看实时数据集成平台如何赋能企业 AI 落地

更多 LDPAI 场景细节,敬请期待 5 月 10 日(今天)的 Tapdata 发布会。 最近几个月,AI 领域可谓经历了近十年以来最为魔幻且不可思议的时刻。 自 ChatGPT 发布以来,无论是底层大模型、训练框架、应用框架还是 GPT 插件等…

如何将m4v转换成mp4格式?这些方法极速无损

如何将m4v转换成mp4格式?众所周知,M4V文件格式是一个由苹果公司开发的视频文件格式,它通常用于iTunes Store中售卖和租赁的电影、电视节目等内容。但是,在某些情况下,我们可能无法在其他设备或软件上播放M4V文件&#…

2023年杭州助理工程师职称申报要求和申报材料是什么呢?

一、杭州助理工程师职称申报条件要求: 1、中专学历毕业后,任技术员满四年或未认定技术员参加工作满六年,必须参加考核,考试合格才能成为助理级职称资格 2、大专学历毕业后,三年工作经验,考核合格&#xf…

【AWS入门】利用CloudWatch监控EC2的CPU负载情况

创建一个 EC2 实例 User data 配置如下 #!/bin/bash sudo -i amazon-linux-extras install epel -y yum install stress -y导航到 Cloudwatch->Metrics->All metrics-EC2->Per-Instance Metrics,选中创建的 EC2的 CPU 利用率,点击铃铛标识创建 alarm 设…

以实战学习pandas使用方式:统计考生成绩统计及分布

以实战学习pandas使用方式:统计考生成绩统计及分布 引子需求逐步实现使用 pandas 读 excel初始化一些数据获取 excel 列名获取总表的统计数据分班级数据各科目比率统计统计名次分布 写入文件小结 引子 老顾日常工作,是用不到 python 的,所以…

vue-admin-template中vue动态路由不显示问题解决

使用的的是vue-admin-template,这是一个极简的 vue admin 管理后台,它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。需要根据自己的需求二次开发。 线上地址:vue-admin-tem…

【操作系统】进程调度

目录 调度的概念 调度目标 所有系统 批处理系统 交互式系统 实时系统 调度算法 非抢占式调度算法 先来先服务 最短作业优先 非抢占式优先级调度 抢占式调度算法 最短剩余时间优先 轮转调度 抢占式优先级调度 多级反馈队列 彩票调度 公平分享调度 调度的概念 进程是资源分配…

Windows Nvm安装

前言 在windows系统下安装的是nvm-windows,nvm只支持安装在在Linux和Mac系统下。之前在Linux上安装过,最近在Windows上安装,特记录一下。 下载 下载地址:传送门 安装 双击exe文件,选定安装路径,下一步…

在外SSH远程连接macOS服务器【cpolar内网穿透】

文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

动态库和静态库的使用

一、什么是库? 库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。 常见的库类型 共享库 静态库 动态库…

数据管理证书有哪些?DAMA-CDGA/CDGP含金量高

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

小度即将推出智能手机产品,醉翁之意意在何为?

5月8日,智哪儿从相关渠道获悉,小度即将于5月下旬发布首款智能手机产品。小度科技通过公开渠道确认了上述信息并透露将于下周披露更详细的产品信息。根据市场调查机构Counterpoint Research公布的最新报告,2023年第一季度全球智能手机市场出货…

巩飞:构建自治智能的数据库云管平台,加速国产数据库应用进程

导语 4月8日下午,为期两天的第十二届数据技术嘉年华(DTC 2023)在北京新云南皇冠假日酒店圆满落下帷幕。大会以“开源融合数字化——引领数据技术发展,释放数据要素价值”为主题,汇聚产学研各界精英到场交流。云和恩墨数…

什么是医学影像PACS系统?PACS系统功能有哪些?作用有哪些?对接哪些设备?业务流程是什么?

一、什么是医学影像PACS系统 PACS:为Picture Archive and CommunicationSystem的缩写,是图象归档和通讯系统。PACS系统应用在医院影像科室的系统,主要的任务就是把日常产生的各种医学影像(包括核磁,CT,超声…

入门PyTorch的学习路线指南

PyTorch是目前最受欢迎的深度学习框架之一,它具有易于使用、灵活性强、支持动态图等优点,因此备受研究者和工程师的青睐。如果你想学习PyTorch,下面是一个入门PyTorch的学习路线。 学习基础知识: 学习Python编程语言:…

从入门到精通:教你如何使用Page Object模式提高WebUI自动化测试质量

目录 前言 什么是Page Object模式? 如何编写Page Object模式测试脚本? 步骤1:创建页面对象类 步骤2:编写测试用例 步骤3:运行测试用例 总结 前言 在进行Web应用程序开发的时候,我们经常需要进行自动…