Java中的I/O讲解(超容易理解)(下篇)

如果想观看更多Java内容 可上我的个人主页关注我,地址
子逸爱编程-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/a15766649633?type=blog

使用工具 IntelliJ IDEA Community Edition 2023.1.4

使用语言 Java8 

代码能力快速提升小方法,看完代码自己敲一遍,十分有用 

目录

1.数据操作流 

1.1 DataOutputStream类和DataInputStream类 

1.2 数据操作流贯穿示例 

1.3 小结 

2. 序列化和反序列化 

2.1 序列化和反序列化

2.1.1序列化和反序列化基本概念

2.2 对象输出流ObjectOutputStream实现序列化 

2.2.1 ObjectOutputStream类的常用方法 

2.2.2 序列化贯穿示例 

2.3 对象输入流ObjectInputStream实现反序列化

2.3.1 对象输入流ObjectInputStream的基本概念

2.3.2 对象输入流ObjectInputStream的常用方法

2.3.3 反序列化贯穿示例

2.3.4 Java体系中常用流的分类


 

1.数据操作流 

前面学习的各类流实现了对文本文件的读写操作,但常见的文件读写操作还有一种二进制文件的读写操作。接下来介绍数据操作流DataOutputStream和DataInputStream,使用它们实现对二进制文件的读写操作。

1.1 DataOutputStream类和DataInputStream类 

DataOutputStream类是OutputStream类的子类,利用DataOutput类写二进制文件的实现步骤与使用FileOutputStream类写文件的步骤极其相似,而且用到了FIleOutputStream类。同样,DataInputStream类是InputStream的子类,在使用上也与FileInputStream类很相似。 

使用这个可以操作视频,图片,音频等二进制文件。 

不使用数据操作流字节流的多样性将会缩减,字节流也可以先进行缓冲流再进行数据操作流,字节缓冲输入流类名:BufferedOutputStream,字节缓冲输出流类名:BufferedInputStream,用法与字符的相同,只不过如果要使用数据操作流还要再创建一个数据操作流,然后把缓冲流作为参数丢进去(也可以不使用缓冲,直接把字节流); 

1.2 数据操作流贯穿示例 

示例代码 

运行以上这段代码将把"E:\\微信图片_20230911081149.jpg"这个路径的图片二进制文件拷到"./img/image.jpg"路径中 

1.3 小结 

DataOutputStream类可以按照与平台无关的方式(就是不管你是什么平台,Windows,Mac什么的都可以)向流中写入基本数据类型的数据,如int、float、long、double和boolean等。此外,DataOutputStream类的writeUTF()方法能写入采用UTF-8字符编码的字符串。 

FileOutputStream out1=new FileOutputStream("路径");
DataOutputStream out=new DataOutputStream(out1);
out.writeByte(1);//其他的基本数据类型也可以,改最后的数据类型就可以了
out.writeUTF("Hello");

DataInputStream类与DataOutputStream类搭配使用,可以按照与平台无关的方式从流中读取基本数据类型的数据,如int、float、long、double和boolean等。此外,DataInputStream类的readUTF()方法能读取采用UTF-8字符编码的字符串。 

FileInputStream in1=new FileInputStream("路径");
DataInputStream in=new DataInputStream(in1);
System.out.println(in.readByte());//其他的基本数据类型也可以,改最后的数据类型就可以了
System.out.println(in.readUTF()); 

2. 序列化和反序列化 

2.1 序列化和反序列化

2.1.1序列化和反序列化基本概念

在设置中的检查把这个打勾,可以在类名处按alt+enter就可以创建序列号; 

对象序列化和反序列化操作时可能会遇到版本兼容性问题。在对象进行序列化或反序列化操作的时候,要考虑JDK版本。如果序列化的JDK版本和反序列化的JDK版本不统一,就有可能发生错误。所有在序列化操作中引入了一个serialVersionUID的常量,可以通过此常量验证版本的一致性。在进行反序列化时,JVM会把传来的字节流中的serialVarsionUID与本地相应实体(类)的serialVarsionUID进行比较。如果二者相同,就认为版本是一致的,可以进行反序列化;否则会出现序列化版本不一致的异常。
当实现java.io.Serializable接口的类没有显示定义名为serialVersionUID、类型为long的变量是,Java序列化机制在编译时会自动生成一个此版本的serialVersionUID变量。如果不希望通过编译自动生成,也可以直接显示定义这个变量。
例如,可以在Person类中加入以下常量:
private static final long serialVersionUID=1L; 

序列化时包名和文件名不能为中文,要规范,不然会运行错误;

在前面的内容中实现了通过java程序读写文件。事实上,在开发中检查需要将对象的信息保存在磁盘中以便以后检索。可以将对象中的属性信息逐一记录到文本文件中,但这样程序员不得不为每一个对象编写代码;当使用时再将这些信息从文本文件中还原,这样需要对对象中的信息进行逐一处理,过程很烦琐且非常容易出错,而序列化提供了实现这个目标的便捷方法。

简单来说,序列化就是将对象的状态更轻松简单地存储到特定的存储介质中的过程,也就是将对象状态转换为可保持或可传输的过程。使用序列化的意义也在于将java对象序列化后,可以将其转换成字节序列,这些字节序列可以被保存在磁盘上,也可以借助网络进行传输,同时序列化后的对象保存的是二进制状态,这样实现了平台无关性,即可以将在Windows操作系统中实现序列化的一个对象,传输到Linux操作系统的机器上。反序列化时将特定的存储介质中的数据重新构建对象的过程,通过反序列化后得到相同对象,而无需担心数据因平台不同出现异常。

实现序列化和反序列化操作,需要使用对象操作流,下面将分别介绍对象输出流(ObjectOutputStream)和对象输入流(ObjectInputStream); 

2.2 对象输出流ObjectOutputStream实现序列化 

简单来说,对象的序列化,是把一个对象变为二进制的数据流的一种方法,通过对象序列化可以方便地实现对象的传输和存储。如果一个类的对象需要被序列化,则这个对象所属类必须实现java.io.Serializable;这个一定一定不要忘记了!!!超级超级重要,没加的话是无法序列化的。 

因为在此接口中并没有定义任何方法,所以次接口是一个标识接口。一旦某个类实现了Serializable接口,该类的对象就是可序列化的。在JDK1.8类库中有些类(如String类、包装类和日期时间类等)实现了Serializable接口。现创建一个Person类,并标记该类的对象时可序列化的,代码如下: 

在上面的代码中,因为Person类已经实现了Serializable接口,所以此类的对象时可以被序列化的,而如果完成序列化操作,就还需要依靠对象输出流,他可以将对象转成二进制字节数据输出到文件中保存。

2.2.1 ObjectOutputStream类的常用方法 

ObjectOutputStream(OutputStream out)创建对象输出流对象构造方法
final void writeObject(Object obj)将指定对象写入流实例方法

2.2.2 序列化贯穿示例 

示例代码 

执行以上代码将会在""./test/user/"目录下创建一个"test1.bat"文件,然后里面就是序列化的对象;

使用普通的对象也是同理,做法相同;


以上的获取路径方法可以记一下 ;

2.3 对象输入流ObjectInputStream实现反序列化

2.3.1 对象输入流ObjectInputStream的基本概念

既然能将对象的状态保存在存储介质中,那么如何将这些对象状态读取出来呢?这就要用到反序列化。反序列化就是序列化的相反操作,序列化是将对象的状态信息保存到存储介质中的过程,反序列化则是从特定存储介质中读取数据并重新构建成对象的过程。通过反序列化,可以将存储在文件上的对象信息读取出来,然后重新构建为对象。这样就不需要再将文件上的信息一一读取、并分析,重新组织为对象。

通常,对象中的所有属性都会被序列化,但是对于一些比较敏感的信息,如用户的密码,一旦序列化,人们完全可以通过读取文件或拦截网络传输数据的方式获得这些信息。因此,出于安全考虑,某些书香苑应限制被序列化,解决的办法是使用transient关键字修改不需要序列化的对象属性。

例如,若希望Person对象中的年龄信息不被序列化,只需在Person类的age属性前添加transient关键字,如下所示
private transient int age;
在完成以上修改后,age属性将被限制序列化;

2.3.2 对象输入流ObjectInputStream的常用方法

执行反序列化操作需使用对象输入流ObjectInputStream,他可以直接把序列化后的对象还原。ObjectInputStream类的常用方法如下所示:

ObjectInputStream(InputStream in)创建对象输入流对象构造方法
final Object readObject()从指定位置读取对象实例对象

 在反序列化时,readObject()方法返回的是Object对象,因此,如果需要转换为Person对象,则需进行强制类型转换;

2.3.3 反序列化贯穿示例

示例代码 

 运行结果

 

如果序列化中的对象是普通的对象也是同理,做法相同;
如果使用序列化方式向文件中写入多个对象,那么反序列化恢复对象时,也按照写入的顺序读取。 

2.3.4 Java体系中常用流的分类

分类字节输出流字节输入流字符输出流字符输入流
基类OutputStreamInputStreamWriterReader
文件流FileOutputStreamFileInputStreamFileWriterFileReader
缓冲流BufferedOutputStreamBufferedInputStreamBufferedWriterBufferedReader
对象流ObjectOutputStreamObjectInputStream
数据操作流DataOutputStreamDataInputStream

 

所有的基类都是抽象类,无法直接创建实例,需要借助其实现类。
所有的输出流用于实现写数据操作,所有的输入流用于实现读取操作。这个输入和输出是相对程序而言的。
所有的文件流直接与存储介质关联,也就是需指定物理节点,属于节点流,其他流的创建需要在节点流的基础上进行封装,使其具有特殊的功能。例如,缓冲流在节点流的基础上增加缓冲区,对象流在节点流的基础上可实现序列化对象。
操作文本文件时,应使用字符流。字节流可以处理二进制数据,它的功能比字符流更强大。因为计算机里所有的数据都是二进制数据,如果字节流处理文本文件,还需要把这些字节转成字符,就增加了编程的复杂度,降低了执行效率。所以当输入和输出是文本文件时,尽量使用字符流。如果是二进制文件,则应考虑使用字节流。 

在实际开发中,可能会使用到其他类型的I/O流,它们也是四个抽象基类的实现类,用到时可查阅API帮助文档自行学习。 

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

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

相关文章

简易指南:国内ip切换手机软件怎么弄

在网络访问受到地域限制的情况下,使用国内IP切换手机软件可以帮助用户轻松访问被屏蔽的内容,扩展网络体验。以下是虎观代理小二分享的使用国内IP切换手机软件的简易指南。并提供一些注意事项。 如何在手机上使用国内IP切换软件 步骤一:选择I…

idea2023 运行多 springboot 实例

概要 1、修改idea运行多实例(本地测试负载) 你可能用到其他 1、改造项目缓存token 至redis 支持负载均衡部署 SpringSecurity6.0RedisJWTMP基于token认证功能开发(源码级剖析可用于实际生产项目)_springsecurity redis管理token…

嵌入式学习第二十九天!(数据结构的概念、单向链表)

数据结构: 1. 定义: 一组用来保存一种或者多种特定关系的数据的集合(组织和存储数据) 1. 程序设计: 将现实中大量而复杂的问题以特定的数据类型和特定的数据结构存储在内存中,并在此基础上实现某个特定的功…

安装调试kotti_ai:AI+互联网企业级部署应用软件包@riscv+OpenKylin

先上结论:riscvOpenKylin可以安装pyramidkottikotti_ai 但是paddle_serving_client无法安装,项目的AI实现部分需要改用其它方法,比如onnx。最终onnx也没有装成,只好用飞桨自己的推理。 安装kotti pip install kotti 安装kotti和…

postman测试文件上传接口

java里编写一个导入接口,接口的入参就是一个文件,此时接口中使用的接收参数是 用postman测试这个接口时:Body里选择类型是form-data Header中自动修改了Content-Type 如果既要上传文件,又要输入参数可使用如下方式: 此…

训练svm并部署树莓派

训练svm并部署树莓派 开发环境1. 准备数据集2. 训练模型3. 部署模型开发环境 vscode python 3.8 用到的库: scikit-learn==1.3.2 pickle torch pandas matplotlib 1. 准备数据集 数据为xls文件,如下格式 2. 训练模型 文件结构 执行训练 python代码 import pickle &…

递归和递推的区别

目录 1、递推 2、递归 3、结言 递归 递推 1、递推 递推就是说从初值出发后一直运算到所需的结果。 ——从已知到未知。(从小到大) 举一个简单的例子: 每天能学习一个小时的编程,那么一个月之后可以学到三十小时的编程知识。…

vue项目突然报错 error Insert `⏎·········` prettier/prettier

vs设置了保存时自动格式化代码,突然就报错: 解决方法,在.eslintrc.js最后添加一行:prettier/prettier: off, 然后重新运行

C#多态性

文章目录 C#多态性静态多态性函数重载函数重载 动态多态性运行结果 C#多态性 静态多态性 在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为: 函数重载 运算符重载 运算符重载将…

UnityShader(十九) AlphaBlend

上代码: Shader "Shader入门/透明度效果/AlphaBlendShader" {Properties{_MainTex ("Texture", 2D) "white" {}_AlphaScale("AlphaScale",Range(0,1))1.0}SubShader{Tags { "RenderType""Transparent&quo…

视频转音频怎么转? 5个详细的方法~

将视频中的音频提取为音频文件,不仅可以帮助我们在学习和教育环境中使用,例如在听力练习、语言学习或课堂教学中,还可以帮助我们创建音频片段、音乐或声音效果。下面就向大家从5个不同的角度:软件、在线网站、视频剪辑工具、命令工…

【深度学习基础知识】IOU、GIOU、DIOU、CIOU

这里简单记录下IOU及其衍生公式。   为了拉通IOU及其衍生版的公式对比,以及方便记忆,这里用一个统一的图示来表示出所有的参数 【A】目标框的区域【B】预测框的区域【C】A与B的交集【&#xff…

docker安装Milvus

docker安装Milvus 拉去CPU版本的milvus镜像 $ sudo docker pull milvusdb/milvus:0.10.0-cpu-d061620-5f3c00 docker pull milvusdb/milvus:0.10.0-cpu-d061620-5f3c00 mkdir -p milvus/conf cd milvus/conf ls wget https://raw.githubusercontent.com/milvus-io/milvus/v0.1…

springboot项目yml文件中${}的使用

作用 项目启动时可以灵活的通过修改环境变量来替换配置中的值,如果没有传该环境变量时,就是用默认值; 格式:${自定义参数名:默认值} 代码举例,已开启应用的端口号为例: server: port: ${SERVER_PORT:9…

PC1000A双通道高精度线性恒流LED控制芯片,只需极少极少外围元件

概述 PCD1000A 是一款线性恒流 IC,输出电流可调,恒流精度高,应用方案简单,成本和阻容降压相当,具有过温保护功能,更安全,更可靠。 特点 输出电流可调 5mA-60mA, 恒 流精度可以达…

【Python爬虫】网络爬虫:信息获取与合规应用

这里写目录标题 前言网络爬虫的工作原理网络爬虫的应用领域网络爬虫的技术挑战网络爬虫的伦理问题结语福利 前言 网络爬虫,又称网络爬虫、网络蜘蛛、网络机器人等,是一种按照一定的规则自动地获取万维网信息的程序或者脚本。它可以根据一定的策略自动地浏…

OpenLayers基础教程——使用WebGL加载海量数据(1)

1、前言 最近遇到一个问题:如何在OpenLayers中高效加载海量的场强点?由于项目中的一些要求,不能使用聚合的方法加载。一番搜索之后发现:OpenLayers中有一个WebGLPoints类,使用该类可以轻松应对几十万的数据量&#xf…

【链表】Leetcode 25. K 个一组翻转链表【困难】

K 个一组翻转链表 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改…

【python_往企业微信群中发送文件】

python_往企业微信群中发送文件 这个是用企业微信群机器人的功能,没有用到后台应用。群机器人 #-*- coding:utf-8-* import requests#类型:voice,file file_type"file" file_path"D:\desktop\不过.jpg" webhookkey"xxxx"#…

Mysql与MyBatis

1 Sql语句 增删改查 1.1 建表 -- cmd展示数据库 show databases ; -- cmd登录数据库 mysql localhost -u root -p-- auto_increment 自动增长,每添加一个表项id自动增1 -- char定长字符串 0-255,不足十个字符按十个字符算, varchar变长字符串…