Java研学-IO流(三)

六 字节流 – 字节输出流系列 OutPutStream体系

1 OutPutStream系列 – 字节输出流

// 表示字节输出流所有类的超类,输出流接受输出字节并将其发送到某个接收器
public abstract class OutputStream

FileOutputStream/BufferedOutputStream

2 FileOutputStream类设计

// 用于写入如图像数据的原始字节流,可实例化OutPutStream对象
public class FileOutputStream// 当前路径下创建指定名字的文件
public FileOutputStream(String name)// 例子
public class Test {public static void main(String[] args) {FileOutputStream fo=null;try {fo=new FileOutputStream("play2.txt");// public void write(byte[] bs)  写入字节数组// public void write(int b)  写入一个字节// public void write(byte[] bs,int start,int len)  写入字节数组,自指定位置始写指定长度fo.write(97);  // afo.write("\r\n".getBytes());  // 换行fo.write("这里是一段文字通过字符串转换".getBytes(),0,12);// 这里是一 2字节1汉字} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fo!=null){try {fo.close();} catch (IOException e) {e.printStackTrace();}}}}
}

  由于计算机中底层操作的都是字节数据,而OutputStream正好也是字节流,因此可以直接将数据写入到指定文件中,不需flush

3 BufferedOutputStream类设计 需flush

// 该类实现缓冲输出流,可直接向底层输入流写入字节
public class BufferedOutputStream// 通过传递OutputStream实现类对象完成对文件的操作
public BufferedOutputStream(OutputStream out)// 例子
public class Test {public static void main(String[] args) {BufferedOutputStream bo=null;try {bo=new BufferedOutputStream(new FileOutputStream("play.txt"));bo.write(66);bo.write("\r\n".getBytes());bo.write("烤鸡翅膀我最爱吃".getBytes(),0,12);// 烤鸡翅膀  1汉字2字节bo.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(bo!=null){try {bo.close();} catch (IOException e) {e.printStackTrace();}}}}
}

  BufferedOutputStream不能直接将数据写入到指定文件中,因为其操作的是缓存区,需要将数据刷新到指定的文件中:,建议使用BufferedOutputStream操作字节流可降低内存资源的消耗

七 字节流 – 字节输入流系列 InputStream体系

1 InputStream系列 – 字节输入流

// InputStream 类设计
Class InputStream

FileInputStream/BufferedInputStream

2 FileInputStream类设计

// 用于读取图像等数据的原始字节流
public class FileInputStream// 打开与实际文件的链接创建FileInputStream文件,由name命名读取文件中的数据,可实例化 InputStream类对象
public FileInputStream(String name)// 例子
public class Test {public static void main(String[] args) {FileInputStream fi=null;try {fi=new FileInputStream("play.txt");int data=0;byte[] bs=new byte[1024*5];while ((data=fi.read(bs))!=-1){System.out.println(new String(bs,0,data));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {fi.close();} catch (IOException e) {e.printStackTrace();}}}
}

  一个汉字(包括数字)在UTF-8编码下占用3个字节,在GBK编码下占用2个字节。因此,如果4个汉字存储需要12个字节,那么可以推断出这些汉字是在UTF-8编码下存储的。具体存储方式是将每个汉字转换为UTF-8编码下的3个字节,共计12个字节存储。

3 BufferedInputStream类设计

// 直接操作缓存区降低内存消耗
public class BufferedInputStream// 读取InputStream 参数实现类指定的文件,创建一个BufferedInputStream并保存其参数,内部缓冲区数组创建并存在buf
public BufferedInputStream(InputStream in)// 例子
public class Test {public static void main(String[] args) {BufferedInputStream bi=null;try {bi=new BufferedInputStream(new FileInputStream("play.txt"));int data=0;byte[] bs=new byte[1024*5];while ((data=bi.read(bs))!=-1){System.out.println(new String(bs,0,data));}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if(bi!=null){bi.close();}} catch (IOException e) {e.printStackTrace();}}}
}

字节流小结

  字节流高效流(带有Buffered缓存技术的流),没有像字符流那样提供高效的方法(newLine()和readLine());定义字节高效流的原因,就是操作缓存区代替直接操作系统底层,降低系统资源消耗;

八 例子

将指定盘符下的指定文件,复制粘贴到指定的盘符

public class FC {// 实现盘符下文件的读写操作,startName原文件名,endName目标文件名public void copy(String startName,String endName){// 分别定义两个字符高效流对象BufferedReader start=null;BufferedWriter end=null;try {// 分别实例化对象start=new BufferedReader(new FileReader(startName));end=new BufferedWriter(new FileWriter(endName));String data=null;while ((data=start.readLine())!=null){// 读一行写一行end.write(data);end.newLine();end.flush();}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {// 防止start.close();出现异常导致end.close();无法关闭// 关闭多个异常时需要分别关,关闭资源操作是没有顺序的if (start!=null){try {start.close();} catch (IOException e) {e.printStackTrace();}}if (end!=null){try {end.close();} catch (IOException e) {e.printStackTrace();}}}}
}

九 序列化

1 流转换

在这里插入图片描述
开发中可使用更高效的替代品

InputStreamReader – System.in — Scanner

OutPutStreamWriter – System.out.print()

2 序列化与反序列化

① 序列化:指使用指定的技术(OutputStream流,ObjectOutputStream类),将对象中的数据(通过对象调用方法获取的结果),存储到指定的文件中(也就是写的过程),或通过网络上传的过程

② 反序列化:将指定文件中或网络上的对象中的数据获取到(也就是读操作InputStream流,ObjectInputStream类)

// 创建序列化对象
public class Dog implements Serializable {// 将序列化号固定为常量private static final long serialVersionUID=1L;// Serializable接口是一个声明接口,他没有任何抽象方法,但想实现序列化反序列化操作必须实现它private String name;private int kg;public  Dog(){super();}public Dog(String name, int kg) {super();this.name = name;this.kg = kg;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getKg() {return kg;}public void setKg(int kg) {this.kg = kg;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", kg='" + kg + '\'' +'}';}
}// 序列化
public class DXTest {public static void main(String[] args) {// 声明序列化操作流对象ObjectOutputStream oo=null;try {oo=new ObjectOutputStream(new FileOutputStream("play.txt"));// 实例化需序列化的对象Dog yellow = new Dog("大黄",24);// public void writeObject(Object obj) 将序列化对象写入流中(需要flush)oo.writeObject(yellow);oo.flush();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(oo!=null){try {oo.close();} catch (IOException e) {e.printStackTrace();}}System.out.println("成功上传");}}
}// 反序列化
public class DFTest {public static void main(String[] args) {// 声明反序列化对象ObjectInputStream oi=null;try {oi=new ObjectInputStream(new FileInputStream("play.txt"));// public Object readObject() 将文件中的对象读出来 序列化对象接收是Object因此需要强转Dog yellow= (Dog) oi.readObject();System.out.println(yellow.toString());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {if(oi!=null){try {oi.close();} catch (IOException e) {e.printStackTrace();}}}}
}

  上传数据(序列化),是将数据以字节码的形式存储到指定的文件中,打开文件之后,无法直接阅读,需要下载(反序列化)后才能阅读
  在类的序列化过程中,如果添加新的属性,需要再次进行序列化和反序列化,这样同步操作才能不报错,如果一个没做,就会出现类无效异常 java.io.InvalidClassException

// 其中 stream classdesc serialVersionUID = 4216129340136042751 是本地读取类的序列化号
// local class serialVersionUID = 8800134341386811038 是本次已经存在的序列化号
java.io.InvalidClassException: com.Test.Dog; local class incompatible: stream classdesc serialVersionUID = 4216129340136042751, local class serialVersionUID = 8800134341386811038

  读取就是反序列化操作;而已存在就是序列化操作,两个版本号不同就会出现异常
  为了避免异常的出现,序列化后版本号进行固定;一般在实现序列化接口后,在类中(Dog类)将序列化号直接定义为常量

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

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

相关文章

Elasticsearch分词器--空格分词器(whitespace analyzer)

介绍 文本分析,是将全文本转换为一系列单词的过程,也叫分词。analysis是通过analyzer(分词器)来实现的,可以使用Elasticearch内置的分词器,也可以自己去定制一些分词器。除了在数据写入时将词条进行转换,那么在查询的时…

2023-简单点-机器学习中矩阵向量求导

机器学习中矩阵向量求导的概念是什么? 在机器学习中,矩阵向量求导的概念主要涉及对函数中的矩阵或向量参数进行求导运算。这种求导运算可以帮助我们了解函数值随参数的变化情况,进而应用于优化算法中。具体来说,当损失函数是一个…

ElasticSearch知识体系详解

1.介绍 ElasticSearch是基于Lucene的开源搜索及分析引擎,使用Java语言开发的搜索引擎库类,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。 它可以被下面这样准确的形容: 一个分布式的实时文档存储&#xf…

图解java.util.concurrent并发包源码系列——深入理解定时任务线程池ScheduledThreadPoolExecutor

深入理解定时任务线程池ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor作用与用法ScheduledThreadPoolExecutor内部执行流程DelayedWorkQueueScheduledFutureTask源码分析任务提交ScheduledFutureTask的属性和方法delayedExecute(t) 任务执行ScheduledFutureTask.su…

软件测试计划书

测试计划书 1.测试参考文档和测试提交文档 2.测试进度计划 3.测试资源 4.系统风险、优先级 5.测试策略 6.缺陷管理 7.测试停止标准 软件开发全文档下载进入主页。

Elasticsearch 如何处理 Aggs 顺序中的大写字母和小写字母?

Elasticsearch 排序允许你根据特定条件对搜索结果进行排序。 然而,在排序时处理区分大小写时,Elasticsearch 将大写和小写字母视为不同的字符,分别对它们进行排序。 这是因为 ASCII 表顺序是从大写 A 到小写 z。 默认情况下,Elas…

微信小程序 地图撒点

1. 微信小程序 地图撒点 1.1 说明 首先使用微信小程序自带标签,并且设置好宽高让地图显示,用longitude和latitude表示中心点。   (1)show-location 显示带有方向的当前定位点,本项目不需要不添加。   (2&#xff…

基于机器深度学习的交通标志目标识别

在线工具推荐: 三维数字孪生场景工具 - GLTF/GLB在线编辑器 - Three.js AI自动纹理化开发 - YOLO 虚幻合成数据生成器 - 3D模型在线转换 - 3D模型预览图生成服务 智能交通系统(ITS),包括无人驾驶车辆,尽管在道路…

Unittest单元测试之unittest用例执行顺序

unittest用例执行顺序 当在一个测试类或多个测试模块下,用例数量较多时,unittest在执行用例 (test_xxx)时,并不是按从上到下的顺序执行,有特定的顺序。 unittest框架默认根据ACSII码的顺序加载测试用例&a…

SHAP(三):在解释预测模型以寻求因果见解时要小心

SHAP(三):在解释预测模型以寻求因果见解时要小心 与 Microsoft 的 Eleanor Dillon、Jacob LaRiviere、Scott Lundberg、Jonathan Roth 和 Vasilis Syrgkanis 合作撰写的关于因果关系和可解释机器学习的文章。 当与 SHAP 等可解释性工具配合…

CSS 多主题切换思路

前言 本篇仅提供多主题切换思路,示例简单且清晰。 实现 步骤一:多主题(颜色)定义 定义根伪类 :root,代码第 2 和 7 行。分别定义了默认和带参数的伪类;定义 CSS 变量,注意变量名需要以两个减号(--&…

时间戳转换为日期格式(封装)

在前端开发中,后端有时候传过来的数据为时间戳的格式 而我们又需要将其转换为时间格式来回显。所以需要一个可以转换时间戳的工具。 封装函数 构建一个函数,传入我们的时间戳和我们想要的时间格式,通过JavaScript的时间对象方法,…