序列化流

Java提供了一种对象序列化的机制,用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写入到文件中后,就相当于在文件中保存了一个对象信息。

反之,该字节序列还可以从文件读取出来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。

ObjectOutputStream类

java.io.ObjectOutputStream类,将Java对象的原始数据类型写入到文件中,实现对象的持久化存储。

构造方法
  • public ObjectOutputStream(OutputStream out):创建一个指定的OutputStream的ObjectOutputStream类对象
特有的独有方法:
  • void writeObject(Object obj):将指定的对象写入到ObjectOutputStream类对象中。
序列化操作
  1. ​ 一个对象想要能够序列化和反序列化,必须满足两个条件:

    • 该类必须实现java.io.Serializable接口,Serializable接口,是一个标记型接口,如果该类没有实现Serializable接口,将会抛出NotSerializableException。

    • 该类的所有属性必须是可以实现序列化或者反序列化。如果有一个属性不想让它参与序列化,则该属性必须标明是瞬态的,瞬时的,这个关键字是transient

  1. public class Student implements Serializable {
  2. private String name;
  3. private transient Integer age;// 不让age属性参与序列化
  4. }

ObjectInputStream类

java.io.ObjectInputStream类是反序列化流,将之前使用ObjectOutputStream序列化流的原始数据恢复为对象。

构造方法
  • ​ public ObjectInputStream(InputStream in):创建一个指定的InputStream的对象反序列化流对象。
特有的方法:
  • ​ public final Object readObject():从反序列化流中读取一个对象。

对于JVM来说,能够进行反序列的对象 ,前提条件是必须能够找到class文件的类,如果找不到该类的class文件,则会抛出一个ClassNotFoundException异常。

另外,当JVM序列化对象时,能够找到class文件,但是class文件在序列化对象时,发生了修改,那么反序列化操做会抛出一个InvalidClassException异常。原因如下:

  • 该类的序列化版本号与从流中读取出来描述该类的版本号不一致。

  • 该类包含了未知数据类型。

  • 该类没有可访问的无参构造方法。

Serializable接口给需要序列化的类,提供了一个序列化版本号,serialVersionUID 该版本号的目的就是在于验证序列化的对象和对应的类是否是版本一致的。

代码演示:

  1. // 序列化操作类
  2. public class Demo01ObjectOutputStream {
  3. public static void main(String[] args) throws IOException {
  4. //1.创建ObjectOutputStream流对象,构造方法中传递指定的字节输出流。
  5. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day30_IO\\student.txt"));
  6. //2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中。
  7. //2.1 先创建一个对象
  8. Student s = new Student("小孙", 30);
  9. s.score = 60;
  10. //2.2写对象到文件中
  11. oos.writeObject(s);
  12. //3.释放资源。
  13. oos.close();
  14. }
  15. }
  16. // 反序列化类操作
  17. public class Demo02ObjectInputStream {
  18. public static void main(String[] args) throws IOException, ClassNotFoundException {
  19. // 1. 创建一个ObjectInputStream流对象,构造方法中传递一个字节输入流对象
  20. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day30_IO\\student.txt"));
  21. // 2. 使用ObjectInputStream流对象中的方法readObject,读取保存在文件中的对象数据
  22. Object obj = ois.readObject();
  23. // 3.释放资源。
  24. ois.close();
  25. // 4. 查看对象的数据
  26. System.out.println(obj);// Student{name='小孙', age=30}
  27. if ( obj instanceof Student) {
  28. Student student = (Student)obj;
  29. System.out.println(student.getAge() + "--" + student.getName());
  30. } else {
  31. System.out.println("转换失败");
  32. }
  33. }
  34. }
  35. // 需要被序列化的类
  36. import java.io.Serializable;
  37. public class Student implements Serializable {
  38. // 可以选择手动自定义一个序列化版本号
  39. private static final long serialVersionUID = 1L;
  40. //private static String name;
  41. private String name;
  42. private Integer age;
  43. private transient String address = "郑州市";
  44. transient int score;// 0
  45. }

原理分析:

练习:存储一堆对象,实现序列化和反序列化动作。
  1. import java.io.Serializable;
  2. public class Student implements Serializable {
  3. // 可以选择手动自定义一个序列化版本号
  4. private static final long serialVersionUID = 1L;
  5. //private static String name;
  6. private String name;
  7. private Integer age;
  8. private transient String address = "郑州市";
  9. transient int score;// 0
  10. public String getName() {
  11. return name;
  12. }
  13. public void setName(String name) {
  14. this.name = name;
  15. }
  16. public Integer getAge() {
  17. return age;
  18. }
  19. public void setAge(Integer age) {
  20. this.age = age;
  21. }
  22. public String getAddress() {
  23. return address;
  24. }
  25. public void setAddress(String address) {
  26. this.address = address;
  27. }
  28. public Student() {
  29. }
  30. public Student(String name, Integer age) {
  31. this.name = name;
  32. this.age = age;
  33. address = "郑州市";
  34. }
  35. @Override
  36. public String toString() {
  37. return "Student{" +
  38. "name='" + name + '\'' +
  39. ", age=" + age +
  40. ", address='" + address + '\'' +
  41. ", score=" + score +
  42. '}';
  43. }
  44. }
  45. @SuppressWarnings("unchecked")
  46. public class DemoTestSerialize {
  47. public static void main(String[] args) throws IOException, ClassNotFoundException {
  48. //1.定义多个对象,存储在集合中
  49. ArrayList<Student> list = new ArrayList<>();
  50. list.add(new Student("小孙",30));
  51. list.add(new Student("小王",20));
  52. list.add(new Student("小赵",40));
  53. list.add(new Student("小刘",10));
  54. list.add(new Student("小丽",25));
  55. //2.使用序列化技术,把该集合对象写入到文件中
  56. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day30_IO\\student.txt"));
  57. //3.写入进去,调用writeObject
  58. oos.writeObject(list);
  59. //4.使用反序列化技术,把文件中保存的集合对象读取出来
  60. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day3_IO\\student.txt"));
  61. //5.读取对象数据,调用readObject()方法
  62. Object obj = ois.readObject();
  63. //6.向下转型
  64. if (obj instanceof ArrayList){
  65. ArrayList<Student> students = (ArrayList<Student>)obj;
  66. //7.遍历该集合对象
  67. for (Object student:students){
  68. System.out.println(student);
  69. }
  70. }
  71. }
  72. }

打印流

java.io.PrintStream类能够很方便打印各种数据类型的值。

构造方法
  • public PrintStream(String filename):使用指定的文件名创建一个新的打印流对象。
改变打印流的方向

正常System.out就是PrintStream类型的,数据的流动的位置在控制台中。改变数据的流动位置。通过System.setOut(PrintStream print)来改变流向。

  1. PrintStream out = System.out;
  2. out.print(123);// 在控制台中
  3. // 构造方法创建一个打印流对象
  4. PrintStream printStream = new PrintStream("day30_IO\\print.txt");
  5. // 改变打印流的方向为"day30_IO\\print.txt"路径
  6. System.setOut(printStream);
  7. System.out.println("我已经改变了输出数据的位置");
  8. System.out.println("我想在控制台中输出数据");
  9. System.out.println("啦啦啦啦啦");

IO流(03)--序列化流、打印流的更多相关文章

  1. java IO之 序列流 集合对象Properties 打印流 流对象

    序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...

  2. Java:IO流其他类(字节数组流、字符数组流、数据流、打印流、Properities、对象流、管道流、随机访问、序列流、字符串读写流)

    一.字节数组流: 类 ByteArrayInputStream:在构造函数的时候,需要接受数据源,而且数据源是一个字节数组. 包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪 read ...

  3. Java基础知识强化之IO流笔记60:打印流 之 改进复制文本文件的案例

    1. 使用打印流改进复制文本文件的案例 2. 代码示例: package cn.itcast_03; import java.io.BufferedReader; import java.io.Buf ...

  4. Java基础知识强化之IO流笔记59:打印流

    1. 打印流 (1)分类: • 字节打印流   PrintStream • 字符打印流   PrintWriter (2)打印流的特点: • 只能写数据,不能读数据 • 只能操作目的地,不能操作数据源 ...

  5. JAVA学习第五十四课 — IO流(八)打印流 &amp; 序列流

    一.综合练习-文件清单列表 获取指定文件夹下,指定扩展名的文件(含子文件夹),并将这些文件的绝对路径写到一个文本文件里.也就是建立一个指定扩展名的文件列表 1.深度遍历 2.过滤器->容器 3. ...

  6. File类与常用IO流第十一章——打印流

    第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...

  7. 零基础学习java------day17------缓冲字节流,转换字节流,简化流,缓冲字符流,序列化和对象流

    1. 缓冲字节流 缓冲区:缓冲区实质上是一个数组.通常它是一个字节数组,但是也可以使用其他种类的数组.但是一个缓冲区不 仅仅 是一个数组.缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程 ...

  8. IO流_PrintWriter(字符打印流)与PrintStream(字节打印流)

    PrintStream:  1.提供了打印方法可以对多种数据类型值进行打印,并保持数据的表示形式  2.它不抛IOException  3.构造函数接受三种类型的值:  字符串路径  File对象   ...

  9. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

随机推荐

  1. web安全入门--入门条件

    介绍:网络安全由习大大提出,是继海.陆.空.外太空的第五大作战领域,也是一个关系国家安全和主权.社会稳定.民族文化继承和发扬的重要问题.其重要性,正随着全球信息化步伐的加快越来越重要.接下来,我向大家 ...

  2. 带你了解Boom 3D的Mac版音效模式

    音乐是很好的情绪抒发途径,因为音乐蕴含了很多信息,包含了很多情感,所以我们聆听不同种类的音乐的时候会产生不同的心理感受.这就是音乐的魅力,可以让人产生共鸣引发无数的思绪.为了能够更好的体会感受音乐可以 ...

  3. 利用css3和js实现旋转木马图片小demo

    先看效果图: 上源码 html代码 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  4. 安装swoole扩展

    wget https://github.com/swoole/swoole-src/archive/v1.9.3-stable.tar.gz tar -zxvf v1.9.3-stable.tar.g ...

  5. 不一样的Flink入门教程

    前言 微信搜[Java3y]关注这个朴实无华的男人,点赞关注是对我最大的支持! 文本已收录至我的GitHub:https://github.com/ZhongFuCheng3y/3y,有300多篇原创 ...

  6. Linux 学习笔记04丨Linux的用户和用户组管理

    Chapter 3. 用户和用户组管理 由于Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以该账号身份进入系统. 3.0 用户与 ...

  7. mysql 优化数据类型

    1.更小的通常更好 选择不会超过范围的最小类型 2.简单就好 例如,整型比字符操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整形比较更复杂. 3.尽量避免null 如果查询中包含可为nul ...

  8. 【Python】我是如何使计算时间提速25.6倍的

    我是如何使计算时间提速25.6倍的 我的原始文档:https://www.yuque.com/lart/blog/aemqfz 在显著性目标检测任务中有个重要的评价指标, E-measure, 需要使 ...

  9. 对象不支持“assign”属性或方法

    1. 报错信息 vue项目打包部署后,ie11报错内容如下: 看到报错信息肯定是语法兼容问题了,经测试 Edge 无此情况,部分ie9也有此类问题. 2. 尝试方法 安装 create-react-a ...

  10. 基于CefSharp开发(一)开发什么?没想好

    一.创建项目 创建WPF (.Net Core)项目 二.CefSharp引用 程序包管理器控制台引入CefSharp Install-Package CefSharp.Wpf -Version 85 ...