文章目录

  • 序列化
    • 概述
    • ObjectOutputStream类
      • 构造方法
      • 序列化操作
    • ObjectInputStream类
      • 构造方法
      • 反序列化操作1
      • **反序列化操作2**
    • 案例:序列化集合
      • 案例分析
      • 案例实现
  • 打印流
    • 概述
    • PrintStream类
      • 构造方法
      • 改变打印流向

序列化

概述

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化对象的数据对象的类型对象中存储的数据信息,都可以用来在内存中创建对象。看图理解序列化:

ObjectOutputStream类

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

构造方法

  • public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream。

构造举例,代码如下:

FileOutputStream fileOut = new FileOutputStream("employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);

序列化操作

  1. 一个对象要想序列化,必须满足两个条件:
  • 该类必须实现java.io.Serializable 接口,Serializable 是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException
  • 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用transient 关键字修饰。
public class Employee implements java.io.Serializable {public String name;public String address;public transient int age; // transient瞬态修饰成员,不会被序列化public void addressCheck() {System.out.println("Address  check : " + name + " -- " + address);}
}

2.写出对象方法

  • public final void writeObject (Object obj) : 将指定的对象写出。
public class SerializeDemo{public static void main(String [] args)   {Employee e = new Employee();e.name = "zhangsan";e.address = "北京东城区";e.age = 20; try {// 创建序列化流对象ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.txt"));// 写出对象out.writeObject(e);// 释放资源out.close();fileOut.close();System.out.println("Serialized data is saved"); // 姓名,地址被序列化,年龄没有被序列化。} catch(IOException i)   {i.printStackTrace();}}
}
输出结果:
Serialized data is saved

ObjectInputStream类

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

构造方法

  • public ObjectInputStream(InputStream in): 创建一个指定InputStream的ObjectInputStream。

反序列化操作1

如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream读取对象的方法:

  • public final Object readObject () : 读取一个对象。
public class DeserializeDemo {public static void main(String [] args)   {Employee e = null;try {        // 创建反序列化流FileInputStream fileIn = new FileInputStream("employee.txt");ObjectInputStream in = new ObjectInputStream(fileIn);// 读取一个对象e = (Employee) in.readObject();// 释放资源in.close();fileIn.close();}catch(IOException i) {// 捕获其他异常i.printStackTrace();return;}catch(ClassNotFoundException c)  {// 捕获类找不到异常System.out.println("Employee class not found");c.printStackTrace();return;}// 无异常,直接打印输出System.out.println("Name: " + e.name);  // zhangsanSystem.out.println("Address: " + e.address); // beiqingluSystem.out.println("age: " + e.age); // 0}
}

对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个 **ClassNotFoundException** 异常。

反序列化操作2

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

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
  • 该类包含未知数据类型
  • 该类没有可访问的无参数构造方法

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

public class Employee implements java.io.Serializable {// 加入序列版本号private static final long serialVersionUID = 1L;public String name;public String address;// 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.public int eid; public void addressCheck() {System.out.println("Address  check : " + name + " -- " + address);}
}

案例:序列化集合

  1. 将存有多个自定义对象的集合序列化操作,保存到list.txt文件中。
  2. 反序列化list.txt ,并遍历集合,打印对象信息。

案例分析

  1. 把若干学生对象 ,保存到集合中。
  2. 把集合序列化。
  3. 反序列化读取时,只需要读取一次,转换为集合类型。
  4. 遍历集合,可以打印所有的学生信息

案例实现

public class SerTest {public static void main(String[] args) throws Exception {// 创建 学生对象Student student = new Student("老王", "laow");Student student2 = new Student("老张", "laoz");Student student3 = new Student("老李", "laol");ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(student);arrayList.add(student2);arrayList.add(student3);// 序列化操作// serializ(arrayList);// 反序列化  ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("list.txt"));// 读取对象,强转为ArrayList类型ArrayList<Student> list  = (ArrayList<Student>)ois.readObject();for (int i = 0; i < list.size(); i++ ){Student s = list.get(i);System.out.println(s.getName()+"--"+ s.getPwd());}}private static void serializ(ArrayList<Student> arrayList) throws Exception {// 创建 序列化流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));// 写出对象oos.writeObject(arrayList);// 释放资源oos.close();}
}

打印流

概述

平时我们在控制台打印输出,是调用print方法和println方法完成的,这两个方法都来自于java.io.PrintStream类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

PrintStream类

构造方法

  • public PrintStream(String fileName): 使用指定的文件名创建一个新的打印流。

构造举例,代码如下:

PrintStream ps = new PrintStream("ps.txt");

改变打印流向

System.out就是PrintStream类型的,只不过它的流向是系统规定的,打印在控制台上。不过,既然是流对象,我们就可以玩一个"小把戏",改变它的流向。

public class PrintDemo {public static void main(String[] args) throws IOException {// 调用系统的打印流,控制台直接输出97System.out.println(97);// 创建打印流,指定文件的名称PrintStream ps = new PrintStream("ps.txt");// 设置系统的打印流流向,输出到ps.txtSystem.setOut(ps);// 调用系统的打印流,ps.txt中输出97System.out.println(97);}
}

相关文章:
Java流处理之高效读写的缓冲流
Java流处理之转换编码的转换流
File类详解(获取文件名称、大小、路径、创建等)

Java流处理之序列化和打印流相关推荐

  1. Java基础19:IO流—缓冲流、转换流、序列化、打印流、压缩流和解压流

    IO流中的一些其他流:缓冲流.转换流.序列化.打印流.压缩流和解压流 1. 缓冲流 IO流除了一些基本的流,还有在此基础上发展出来的一些更强大的流.比如能够高效读写的缓冲流,能够转换编码的转换流,能够 ...

  2. JavaSE(字符流、IO资源的处理、属性集、ResourceBundle工具类、缓冲流、转换流、序列化、打印流、装饰设计模式、commons-io工具包)

    JavaSE 字符流 字符输入流[Reader] 字符输入流Reader类的概述 字符输入流Reader类的常用方法 FileReader类 FileReader类的概述 FileReader类的构造 ...

  3. Java笔记整理六(File类,递归,字节流IO,字符流IO,流中的异常处理,属性集Properties,缓冲流,转换流,序列化,打印流)

    1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 文件和目录路径名的抽象表示 java把文件和文件夹封装位为一个File类,我们可 ...

  4. 【java笔记】字符流,Properties,序列化,打印流

    字符流 字符流=字节流+编码 package demo04;import java.io.FileInputStream; import java.io.FileNotFoundException; ...

  5. 【02】Java进阶:13-IO资源的处理、属性集、缓冲流、转换流、序列化、打印流、装饰设计模式、commons-io工具包

    day13[Properties类.缓冲流.转换流.序列化流.装饰者模式.commons-io工具包] 今日内容 IO异常处理 Properties类 缓冲流 转换流 序列化\反序列化流 打印流 装饰 ...

  6. Java基础-9(缓冲流,转换流,序列化,打印流,TCP通信程序)

    51.缓冲流 概述 缓冲流,也叫高效流,是对4个基本的FileXxx 流的增强,所以也是4个流,按照数据类型分类: 字节缓冲流:BufferedInputStream,BufferedOutputSt ...

  7. JAVA学习笔记(三十九)-打印流

    import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; i ...

  8. stream流去除对象的值_I/O流(过滤流、对象序列化、字符流)

    过滤流基础 Data Stream 首先我们来介绍一对过滤流:DataInputStream 和 DataOutputStream.这两个类有什么作用呢?首先来思考下面的需求:假设,要把一个 doub ...

  9. java io文件流序列化_Java——Properties集合,Object序列化流与反序列化流,打印流,commons-IO文件工具类...

    一.properties集合 集合对象Properties类,继承Hashtable,实现Map接口,可以和IO对象结合使用,实现数据的持久存储. 特点: Hashtable的子类,map集合中的方法 ...

  10. 【Java基础】Java IO编程:输入输出流、内存流、打印流、缓冲流BufferedReader、扫描流Scanner、序列化与反序列化

    文章目录 第11章.Java IO编程 11.1 文件操作类:File 11.2 字节流与字符流 字节输出流:OutputStream OutputStream类 FileOutputStream类 ...

最新文章

  1. mysql engine innodb myisam 区别
  2. win8计算机管理没有用户组,Win8右键计算机管理提示“该文件没有与之关联的程序”怎么办?...
  3. 大话设计模式之简单工厂模式
  4. SAP RETAIL 如何确定自动补货触发的单据类型 III
  5. android 减少布局层级,Android 布局优化
  6. 2阶节IIR算法C语言源码
  7. C语言 数组排序 – 快速法排序 - C语言零基础入门教程
  8. Java Hex 16进制的 byte String 转换类
  9. Hadoop运行时缺少hadoop dll winutils exe
  10. 服务器网口显示图像,简单的python3web服务器,可以在浏览器中显示图像
  11. gns3 桥接linux,GNS3之与本机桥接步骤
  12. 将子节点中含子节点的json数据转换成ztree适合的json数据格式
  13. 计算机考试表格中的透视图怎么弄,职称计算机考试:创建数据透视表
  14. 网线为什么又叫做双绞线?UTP STP FTP SFTP之间的区别?
  15. HNUSTOJ-1621 Picking Cabbage(状态压缩DP)
  16. 嵌入式RTSP转RTMP设备说明
  17. python安装第三方库的方法
  18. Pytorch|YOWO原理及代码详解(二)
  19. 服务器 exe文件,服务器无故生成exe文件,套路有点深
  20. 数据分析师有发展前景吗?

热门文章

  1. C++ memset()函数和bzero()函数
  2. 单片机C语言任意角度旋转图片,图片任意角度旋转(转)
  3. 在一起计时器_奇妙物理·高中篇:打点计时器基本介绍
  4. HTML做一个简单漂亮的宠物网页(纯html代码)
  5. 新华三杯考前突击---Day4---综合篇
  6. java三年面试题(分布式篇)不定期更新
  7. 毕业季-Java分布式开发面试题
  8. yarn install命令运行报错:无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
  9. win10断网重连宽带(宽带王)强烈推荐, 关键词:自动拨号、IPV6、断网自动重连、无网络自动重连
  10. Duplicate key