IO流(03)--序列化流、打印流
序列化流
Java提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写入到文件中后,就相当于在文件中保存了一个对象信息。
反之,该字节序列还可以从文件读取出来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。
ObjectOutputStream类
java.io.ObjectOutputStream
类,将Java对象的原始数据类型写入到文件中,实现对象的持久化存储。
构造方法
- public ObjectOutputStream(OutputStream out):创建一个指定的OutputStream的ObjectOutputStream类对象
特有的独有方法:
- void writeObject(Object obj):将指定的对象写入到ObjectOutputStream类对象中。
序列化操作
一个对象想要能够序列化和反序列化,必须满足两个条件:
该类必须实现
java.io.Serializable
接口,Serializable接口,是一个标记型接口,如果该类没有实现Serializable接口,将会抛出NotSerializableException。该类的所有属性必须是可以实现序列化或者反序列化。如果有一个属性不想让它参与序列化,则该属性必须标明是瞬态的,瞬时的,这个关键字是
transient
。
public class Student implements Serializable {
private String name;
private transient Integer age;// 不让age属性参与序列化
}
ObjectInputStream类
java.io.ObjectInputStream
类是反序列化流,将之前使用ObjectOutputStream序列化流的原始数据恢复为对象。
构造方法
- public ObjectInputStream(InputStream in):创建一个指定的InputStream的对象反序列化流对象。
特有的方法:
- public final Object readObject():从反序列化流中读取一个对象。
对于JVM来说,能够进行反序列的对象 ,前提条件是必须能够找到class文件的类,如果找不到该类的class文件,则会抛出一个ClassNotFoundException异常。
另外,当JVM序列化对象时,能够找到class文件,但是class文件在序列化对象时,发生了修改,那么反序列化操做会抛出一个InvalidClassException异常。原因如下:
该类的序列化版本号与从流中读取出来描述该类的版本号不一致。
该类包含了未知数据类型。
该类没有可访问的无参构造方法。
Serializable接口给需要序列化的类,提供了一个序列化版本号,serialVersionUID 该版本号的目的就是在于验证序列化的对象和对应的类是否是版本一致的。
代码演示:
// 序列化操作类
public class Demo01ObjectOutputStream {
public static void main(String[] args) throws IOException {
//1.创建ObjectOutputStream流对象,构造方法中传递指定的字节输出流。
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day30_IO\\student.txt"));
//2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中。
//2.1 先创建一个对象
Student s = new Student("小孙", 30);
s.score = 60;
//2.2写对象到文件中
oos.writeObject(s);
//3.释放资源。
oos.close();
}
}
// 反序列化类操作
public class Demo02ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 1. 创建一个ObjectInputStream流对象,构造方法中传递一个字节输入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day30_IO\\student.txt"));
// 2. 使用ObjectInputStream流对象中的方法readObject,读取保存在文件中的对象数据
Object obj = ois.readObject();
// 3.释放资源。
ois.close();
// 4. 查看对象的数据
System.out.println(obj);// Student{name='小孙', age=30}
if ( obj instanceof Student) {
Student student = (Student)obj;
System.out.println(student.getAge() + "--" + student.getName());
} else {
System.out.println("转换失败");
}
}
}
// 需要被序列化的类
import java.io.Serializable;
public class Student implements Serializable {
// 可以选择手动自定义一个序列化版本号
private static final long serialVersionUID = 1L;
//private static String name;
private String name;
private Integer age;
private transient String address = "郑州市";
transient int score;// 0
}
原理分析:
练习:存储一堆对象,实现序列化和反序列化动作。
import java.io.Serializable;
public class Student implements Serializable {
// 可以选择手动自定义一个序列化版本号
private static final long serialVersionUID = 1L;
//private static String name;
private String name;
private Integer age;
private transient String address = "郑州市";
transient int score;// 0
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
address = "郑州市";
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", score=" + score +
'}';
}
}
@SuppressWarnings("unchecked")
public class DemoTestSerialize {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.定义多个对象,存储在集合中
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("小孙",30));
list.add(new Student("小王",20));
list.add(new Student("小赵",40));
list.add(new Student("小刘",10));
list.add(new Student("小丽",25));
//2.使用序列化技术,把该集合对象写入到文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day30_IO\\student.txt"));
//3.写入进去,调用writeObject
oos.writeObject(list);
//4.使用反序列化技术,把文件中保存的集合对象读取出来
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day3_IO\\student.txt"));
//5.读取对象数据,调用readObject()方法
Object obj = ois.readObject();
//6.向下转型
if (obj instanceof ArrayList){
ArrayList<Student> students = (ArrayList<Student>)obj;
//7.遍历该集合对象
for (Object student:students){
System.out.println(student);
}
}
}
}
打印流
java.io.PrintStream
类能够很方便打印各种数据类型的值。
构造方法
- public PrintStream(String filename):使用指定的文件名创建一个新的打印流对象。
改变打印流的方向
正常System.out就是PrintStream类型的,数据的流动的位置在控制台中。改变数据的流动位置。通过System.setOut(PrintStream print)来改变流向。
PrintStream out = System.out;
out.print(123);// 在控制台中
// 构造方法创建一个打印流对象
PrintStream printStream = new PrintStream("day30_IO\\print.txt");
// 改变打印流的方向为"day30_IO\\print.txt"路径
System.setOut(printStream);
System.out.println("我已经改变了输出数据的位置");
System.out.println("我想在控制台中输出数据");
System.out.println("啦啦啦啦啦");
IO流(03)--序列化流、打印流的更多相关文章
- java IO之 序列流 集合对象Properties 打印流 流对象
序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...
- Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)
一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...
- Java基础知识强化之IO流笔记60:打印流 之 改进复制文本文件的案例
1. 使用打印流改进复制文本文件的案例 2. 代码示例: package cn.itcast_03; import java.io.BufferedReader; import java.io.Buf ...
- Java基础知识强化之IO流笔记59:打印流
1. 打印流 (1)分类: • 字节打印流 PrintStream • 字符打印流 PrintWriter (2)打印流的特点: • 只能写数据,不能读数据 • 只能操作目的地,不能操作数据源 ...
- JAVA学习第五十四课 — IO流(八)打印流 & 序列流
一.综合练习-文件清单列表 获取指定文件夹下,指定扩展名的文件(含子文件夹),并将这些文件的绝对路径写到一个文本文件里.也就是建立一个指定扩展名的文件列表 1.深度遍历 2.过滤器->容器 3. ...
- File类与常用IO流第十一章——打印流
第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...
- 零基础学习java------day17------缓冲字节流,转换字节流,简化流,缓冲字符流,序列化和对象流
1. 缓冲字节流 缓冲区:缓冲区实质上是一个数组.通常它是一个字节数组,但是也可以使用其他种类的数组.但是一个缓冲区不 仅仅 是一个数组.缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程 ...
- IO流_PrintWriter(字符打印流)与PrintStream(字节打印流)
PrintStream: 1.提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式 2.它不抛IOException 3.构造函数接受三种类型的值: 字符串路径 File对象 ...
- Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)
1.操作基本数据类型的流 1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...
随机推荐
- 在FL Studio中如何做出渐入的人声效果
当我们在拿到一段人声并想把它加入歌曲中时,如果我们发现人声没有渐入的效果,直接加入到歌曲里出现会变得很突兀的话,我们就需要用到这篇文章所介绍的方法,给人声加上一个渐入的效果. 1. 找到我们需要处理的 ...
- js实现长按显示全部内容
js实现文字超出省略号显示时长按显示全部 元素内容超出省略号显示时长按该元素,生成toast弹窗(id:toolkitContainer),以显示全部内容 #toolkitContainer { ma ...
- Alpha冲刺-第五次冲刺笔记
Alpha冲刺-冲刺笔记 这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE2 这个作业要求在哪里 https://edu.cnblogs. ...
- Python的偏函数
import functools def showag(*args,**kwargs): print(args) print(kwargs) p1 = functools.partial(showag ...
- SQL Server 索引碎片整理
索引碎片整理的四种方法: 1)删除索引并重建 2)使用 DROP_EXISTING 语句重建索引 3)使用 ALTER INDEX REBUILD 语句重建索引 4)使用 ALTER INDEX RE ...
- Flv.js记录(vue)
下载 npm install flv.js 插入 import flvjs from 'flv.js' 第一种报错:Failed to read the 'buffered' property f ...
- moviepy音视频剪辑:使用fl_time进行时间特效处理报错OSError: Error in file xxxx, Accessing time
☞ ░ 前往老猿Python博文目录 ░ 老猿在使用moviepy音视频剪辑的fl_time进行时间特效处理时,系统报错: OSError: Error in file F:\video\WinBas ...
- PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件设置tabsClosable后不能关闭选项卡的原因
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的tabsClosable属性用于控制选项卡栏的每个选项卡是否显示关闭按钮,但显 ...
- PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件概述和属性介绍
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 TabWidget选项卡组件是一个带一到多个选项卡栏和对应页面区域的组件,对应类QTabW ...
- 第8.33节 Python中__getattr__以及__getattr__与__ getattribute__的关系深入剖析
一. 引言 前面几节分别介绍了Python中属性操作捕获的三剑客:__ getattribute__方法.__setattr__方法.__delattr__方法,为什么__ getattribute_ ...