张小飞的Java之路——第四十四章——其他流对象

news/2024/11/24 9:26:22/

写在前面:

视频是什么东西,有看文档精彩吗?

视频是什么东西,有看文档速度快吗?

视频是什么东西,有看文档效率高吗?


诸小亮:这一节,我们介绍一下其他不常用的流对象

张小飞:既然不常用,还学习他们干嘛?

诸小亮:虽然不常用,但是偶尔也会用到,技多不压身嘛

Properties

诸小亮:Properties——HashTable的子类,存储键值对,可以把数据持久化到硬盘上

张小飞:哦?这得见识一下

基本演示

诸小亮:它的使用也很简答

public static void main(String[] args) throws IOException {Properties prop = new Properties();//1. 存储prop.put("yase","19");prop.put("daji","16");prop.put("change","20");//2. 遍历Set<String> names = prop.stringPropertyNames();for(String name : names){System.out.println(name + "----" + prop.get(name));}//修改数据//prop.setProperty("daji","18");
}

结果:
image.png

诸小亮:需要注意,只有键值都是String时,能使用 stringPropertyNames,否则:

image.png 结果:image.png

image.png 结果:image.png

张小飞:明白了,不过,您不是说他能把数据持久化到硬盘上吗?

持久化数据

诸小亮:当然了,首先看它的 list 方法

  • list:可以把Properties中的数据放到一个 OutputStream 中
public static void main(String[] args) throws IOException {Properties prop = new Properties();//1. 存储prop.put("yase","18");prop.put("daji","16");prop.put("change","20");//把内容输出到System.out中prop.list(System.out);
}

结果:image.png 注意:** list 方法一般用于测试**

张小飞:不行,这还是没有保存到文件中

诸小亮:看你急的,使用 store 就能存储数据了

public static void main(String[] args) throws IOException {Properties prop = new Properties();//1. 存储prop.put("yase","18");prop.put("daji","16");prop.put("change","20");//2. 把内容输出到文件中FileOutputStream out = new FileOutputStream("G:\\learn\\hero.properties");//3. 第一个参数是OutputStream对象,第二个参数是备注prop.store(out,"hero info");out.close();
}

结果:image.png

image.png
张小飞:原来输出后,key 和 value 用等号连接了起来

诸小亮:是的,其实——properties是 Java 中最常用的配置文件格式

张小飞:那,现在学习 properties 配置文件吗?

诸小亮:no no no,等到学Java的高级框架时候,才会讲这个

读取properties文件

张小飞:既然存到文件中,那么肯定也能从文件中读取吧

诸小亮:当然可以,使用 load 方法

public static void main(String[] args) throws IOException {Properties prop = new Properties();FileInputStream in = new FileInputStream("G:\\learn\\hero.properties");//1. 加载properties文件prop.load(in);//2. 遍历Set<String> names = prop.stringPropertyNames();for(String name : names){System.out.println(name + "----" + prop.get(name));}in.close();
}

结果:image.png

PrintStream

张小飞:这个 PrintStream 是???

诸小亮:PrintStream——字节打印流,可以把各种类型数据打印到目的地

张小飞:目的地?不是输出到文件中吗?

诸小亮:目的地可以是——File、OutputStream 等对象,包含文件

张小飞:原来是这样

诸小亮:其实我们早就用过这个对象了

张小飞:嗯?什么时候用过?

诸小亮:我们常用的 System.out 就是打印流:

image.png

写入文件

诸小亮:我们先尝试使用 PrintStream 往文件中存储数据

public static void main(String[] args) throws IOException {//1. 创建对象,指定目的地,有两种方式:PrintStream printStream = new PrintStream("G:\\learn\\hero.txt");
//        PrintStream printStream = new PrintStream(new File("G:\\learn\\hero.txt"));//2. 写入字节数据printStream.write("yase".getBytes());//3. 关闭流printStream.close();
}

结果:image.png

常用方法

write

诸小亮:write(int b)——每次写入一个字节

PrintStream printStream = new PrintStream("G:\\learn\\hero.txt");//写入字节数据
printStream.write(97);//97对应的是a
printStream.write(353);//关闭流
printStream.close();

结果:image.png

张小飞:嗯,怎么会这样??????

诸小亮:因为每次只是写入参数的最后一个字节,具体原因:

结果是:aa第一个 a 是 97,第二个 a 对用35397的二进制是:00000000 00000000 00000000 01100001
353转换成二进制是:00000000 00000000 00000001 01100001因为该方法每次只写入一个字节,97353的最后一个字节一样,所以。。。。。

张小飞:明白了,不过每次只写入一个字节,太扯淡了,不能用这个方法

诸小亮:不错,所以它有提供了另一个方法

write

write(byte b[]):写入字节数组中的所有数据

如果就是想写入 “97” 这两个字符,可以使用这个方法,比如:

image.png

结果:image.png

print

print:可以打印各种类型数据到目的地中

image.png

public static void main(String[] args) throws IOException {//创建对象时,指定目的地,常用的两种方式:PrintStream printStream = new PrintStream("G:\\learn\\hero.txt");//打印各种类型数据,println比print多换行功能printStream.println(true);printStream.println(97);printStream.println("yase");printStream.println(3.14);printStream.println('c');//关闭流printStream.close();
}

结果:image.png

PrintWriter

张小飞:不用说了,PrintWriter——肯定是字符打印流,跟 PrintStream 类似

诸小亮:是的,它们的区别在于——PrintWriter 的 write 方法可以直接写入字符串

image.png

ObjectOutputStream

诸小亮:ObjectOutputStream——把 java 对象写入到文件中,称之为:序列化

张小飞:哦?怎么把对象写到文件中?

诸小亮:来,看下面的代码

class Hero {String name;public Hero (String name){this.name = name;}@Overridepublic String toString() {return "Hero{" +"name='" + name + '\'' +'}';}
}public static void main(String[] args) throws IOException {//1. 目的地FileOutputStream out = new FileOutputStream("G:\\learn\\hero.txt");//2. 使用ObjectOutputStream封装FileOutputStreamObjectOutputStream objOut = new ObjectOutputStream(out);//3. 写入java对象Hero hero = new Hero("yase");objOut.writeObject(hero);//4. 关闭流objOut.close();
}

结果:

image.png

张小飞:您这不是报错了吗?

诸小亮:这时因为 Hero 对象没有实现 Serializable 接口,所以不能序列化

张小飞:Serializable 是什么?

诸小亮:Serializable——序列化标识接口,该接口没有任何方法

image.png

诸小亮:但是只有实现Serializable接口的类,才能序列化

张小飞:明白了

诸小亮:修改Hero类,让其实现 Serializable
image.png

张小飞:我又运行了一些,虽然没有报错,但是文件打开是这样子的

image.png

诸小亮:因为 java 对象不是文本数据,所以使用记事本打开会乱码

ObjectInputStream

诸小亮:ObjectInputStream——从文件中读取对象,称之为:反序列化

public static void main(String[] args) throws IOException, ClassNotFoundException {//目的地FileInputStream in = new FileInputStream("G:\\learn\\hero.txt");ObjectInputStream objIn = new ObjectInputStream(in);//从文件中读取对象Hero o = (Hero) objIn.readObject();System.out.println(o.toString());
}

结果:

image.png

张小飞:怎么又报错了? Hero 不是已经实现了 Serializable 接口了吗?

诸小亮:这时因为,缺少一个静态变量serialVersionUI

张小飞:这是????

诸小亮:serialVersionUID: 序列化的版本号,实现Serializable接口,都应该有个这样的静态变量
image.png

注意:变量的值随意
再次序列化后,再次读取image.png

transient

张小飞:transient 是什么意思?

诸小亮:transient——瞬态关键字,瞬态:瞬间状态

张小飞:这是干什么的?

诸小亮:如果有些字段不想被序列化到文件中,可以使用这个修饰符,比如:

image.png

张小飞:您的意思是,这样 name 字段就不会序列化的文件中了?

诸小亮:是的,使用 transient 后,name字段只存在于内存中,不会被写到文件中

再次运行 序列化 和 反序列化,结果:

image.pngimage.png

ByteArrayInputStream 和 ByteArrayOutputStream

张小飞:这是——字节数组–输入输出流?

诸小亮:是的,其实就是用 IO 的读写思想,操作数组

  • ByteArrayInputStream :字节数组输入流,是InputStream的子类

张小飞:什么意思?

诸小亮:之前都是从文件中读取数据,而ByteArrayInputStream,从是字节数组中读取

image.png
张小飞:明白了,所以创建对象时,要传递一个字节数组进去

诸小亮:是的,另外还有 ByteArrayOutputStream

  • ByteArrayOutputStream :字节数组输出流,是 OutputStream 的子类
  • 作用:把数据写到其内部的一个 byte 数组中

张小飞:那是一个可变数组吧

诸小亮:不错,内部的数组会随着数据的不断写入而自动增长

张小飞:能演示一下吗?

诸小亮:当然可以

public static void main(String[] args) throws IOException, ClassNotFoundException {ByteArrayInputStream bin = new ByteArrayInputStream("yase".getBytes());ByteArrayOutputStream bout = new ByteArrayOutputStream();int ch =0;//从ByteArrayInputStream读出,写到ByteArrayOutputStream中while((ch = bin.read()) != -1){//写入内部数组中bout.write(ch);}//获取ByteArrayOutputStream中的数据System.out.println(bout.toString());
}

张小飞:您没有关闭流对象

诸小亮:这两对象操作的都是内存,比较特殊,所以不用close

张小飞:明白了


http://www.ppmy.cn/news/192614.html

相关文章

2023年第三届陕西省大学生网络安全技能大赛--本科高校组 Reverse题解

文章目录 一. 我的upx -d怎么坏了1. 查看节区信息2. 动态调试脱壳3.输出迷宫图4.走迷宫 二. babypython1.字节码简单分析2. gpt分析3. 程序逻辑4.解题脚本 三. BadCoffee1. 相关文章2.解混淆3.解题脚本 四. Web&Assembly(暂时没复现出来,提供一些相关文章)总结 这次比赛做出…

vostro3070装win7_戴尔vostro13-5370笔记本用大包菜U盘安装win7系统的操作教程

戴尔vostro13-5370笔记本机身最薄处仅为15.81mm&#xff0c;重量约为1.41kg&#xff0c;外出携带非常轻松。配备了一块13.3英寸的全高清IPS屏幕&#xff0c;可视角度广&#xff0c;色域高&#xff0c;显示效果好。配备了i5-8250U第八代处理器&#xff0c;内置8GB内存&#xff0…

关于DELL Precision 7550设置U盘启动的方法

关于DELL Precision 7550设置U盘启动的方法 说明步骤 说明 本文测试的电脑为DELL Precision 7550&#xff0c;设置U盘启动的方法。是Windows10 Ubuntu18.04 双系统下修复GRUB引导博文实现的前提。 步骤 1.开机后一直按 F2&#xff0c;出现如下界面 2.按照下图将"Sour…

dell灵越7370 U盘装机 BIOS设置

搞了一晚上&#xff0c;写一下心得。 首先是设置U盘启动&#xff0c;这个网上有但不一定一样。要设置4个地方 步骤&#xff1a; 1、开机按F12进入系统设置选项&#xff0c;选择BIOS Setup进入BIOS设置 2、选择security->PTT security&#xff0c;把第一个PTT On的勾选项…

戴尔G5 5590重装系统

1.进入优盘PE系统 1.1 优盘PE系统 UEFI和Legacy是两种不同的引导方式,UEFI是新式的BIOS,Legacy是传统BIOS。你在UEFI模式下安装的系统,只能用UEFI模式引导;同理,如果你是在Legacy模式下安装的系统,也只能在Legacy模式下进系统。 如果你在做PE是选择的是Legacy,而你电脑…

戴尔poweredge r730服务器配置及系统安装详解教程

第一次给服务器安装的是ubantu系统&#xff1b; 首先我们开机进入小型BIOS设置一下RAID,或者进入服务器管理系统&#xff0c;在系统的BIOS中进行RAID设置&#xff1b; 开机后当看到出现< Ctrl > <R>时按Ctrlr&#xff0c;进入小型BIOS 小型BIOS界面 先进入到VG MG…

表白墙的实现【前后端交互】

目录 一、Servlet API 详解 1. HttpServletRequest 1.1 HttpServletRequest 方法 1.2 getParameter 2.HttpServletResponse 2.1 HttpServletResponse 方法 2.2 代码示例: 设置状态码 2.3 代码示例: 重定向 二、表白墙 1.准备工作 2.约定前后端交互接口 2.1 接口一…

戴尔服务器 Dell R730服务器 Raid5配置

原 Dell R730服务器 Raid5配置 2018年01月23日 18:29:54 And0ne 阅读数&#xff1a;13682 标签&#xff1a; DellRaid 更多 个人分类&#xff1a; Linux 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/qq_15760109/art…