Java IO详解(六)------序列化与反序列化(对象流)

File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html

Java IO 流的分类介绍:http://www.cnblogs.com/ysocean/p/6854098.html

Java IO 字节输入输出流:http://www.cnblogs.com/ysocean/p/6854541.html

Java IO 字符输入输出流:https://i.cnblogs.com/EditPosts.aspx?postid=6859242

Java IO 包装流:http://www.cnblogs.com/ysocean/p/6864080.html

1、什么是序列化与反序列化?

  序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传输)。这个过程称为序列化。通俗来说就是将数据结构或对象转换成二进制串的过程

  反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象模型的过程。也就是将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

2、为什么要做序列化?

  ①、在分布式系统中,此时需要把对象在网络上传输,就得把对象数据转换为二进制形式,需要共享的数据的 JavaBean 对象,都得做序列化。

  ②、服务器钝化:如果服务器发现某些对象好久没活动了,那么服务器就会把这些内存中的对象持久化在本地磁盘文件中(Java对象转换为二进制文件);如果服务器发现某些对象需要活动时,先去内存中寻找,找不到再去磁盘文件中反序列化我们的对象数据,恢复成 Java 对象。这样能节省服务器内存。

3、Java 怎么进行序列化?

  ①、需要做序列化的对象的类,必须实现序列化接口:Java.lang.Serializable 接口(这是一个标志接口,没有任何抽象方法),Java 中大多数类都实现了该接口,比如:String,Integer

  ②、底层会判断,如果当前对象是 Serializable 的实例,才允许做序列化,Java对象 instanceof Serializable 来判断。

  ③、在 Java 中使用对象流来完成序列化和反序列化

    ObjectOutputStream:通过 writeObject()方法做序列化操作

    ObjectInputStream:通过 readObject() 方法做反序列化操作

    

 第一步:创建一个 JavaBean 对象

public class Person implements Serializable{
	private String name;
	private int age;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}  

 第二步:使用 ObjectOutputStream 对象实现序列化

//在根目录下新建一个 io 的文件夹
		OutputStream op = new FileOutputStream("io"+File.separator+"a.txt");
		ObjectOutputStream ops = new ObjectOutputStream(op);
		ops.writeObject(new Person("vae",1));

		ops.close();

  我们打开 a.txt 文件,发现里面的内容乱码,注意这不需要我们来看懂,这是二进制文件,计算机能读懂就行了。

错误一:如果新建的 Person 对象没有实现 Serializable 接口,那么上面的操作会报错:

    

第三步:使用ObjectInputStream 对象实现反序列化

  反序列化的对象必须要提供该对象的字节码文件.class

InputStream in = new FileInputStream("io"+File.separator+"a.txt");
		ObjectInputStream os = new ObjectInputStream(in);
		byte[] buffer = new byte[10];
		int len = -1;
		Person p = (Person) os.readObject();
		System.out.println(p);  //Person [name=vae, age=1]
		os.close();

  

问题1:如果某些数据不需要做序列化,比如密码,比如上面的年龄?

解决办法:在字段面前加上 transient

private String name;//需要序列化
	transient private int age;//不需要序列化

  那么我们在反序列化的时候,打印出来的就是Person [name=vae, age=0],整型数据默认值为 0

问题2:序列化版本问题,在完成序列化操作后,由于项目的升级或修改,可能我们会对序列化对象进行修改,比如增加某个字段,那么我们在进行反序列化就会报错:

解决办法:在 JavaBean 对象中增加一个 serialVersionUID 字段,用来固定这个版本,无论我们怎么修改,版本都是一致的,就能进行反序列化了

private static final long serialVersionUID = 8656128222714547171L;

  

时间: 2024-11-04 19:10:22

Java IO详解(六)------序列化与反序列化(对象流)的相关文章

Java IO 详解

Java IO 详解 初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见. 首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!) 这是java io 比较基本的一些处理流,除此之外我们还会提到一些比较深入的基于io的处理类,比如console类,SteamTokenzier,Externalizable接

Java IO详解(转)

IO是Java及众多编程语言很重要的一块,同时很多程序的瓶颈和耗时操作也都在IO这块. 一.简介 IO操作面临很多问题,信息量的巨大,网络的环境等等,因为IO不仅仅是对本地文件.目录的操作,有时对二进制流.还有一部分是网络方面的资源,所以多种原因直接造成IO操作无疑是耗时且复杂多变的.Java对IO的支持是个不断的演变过程,经过了很多的优化,直到JDK1.4以后,才趋于稳定,在JDK1.4中,加入了nio类,解决了很多性能问题,虽然我们有足够的理由不去了解关于Java IO以前的情况,但是为了学

Java IO详解

学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:618528494  我们一起学Java! 初学Java,一直搞不懂Java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见. 首先看个图:(如果你也是初学者,我相信你看了真个人都不好了,想想java设计者真是煞费苦心啊!) 这是Java io 比较基本的一些处理流

Java IO详解(三)------字节输入输出流

File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html Java IO 流的分类介绍:http://www.cnblogs.com/ysocean/p/6854098.html 那么这篇博客我们讲的是字节输入输出流:InputStream.OutputSteam(下图红色长方形框内),红色椭圆框内是其典型实现(FileInputSteam.FileOutStream)  1.字节输出流:OutputStream public abstrac

java io详解及各输入输出类介绍

首先要记住Java有一个非常强大的 文件及目录类 File, 这里面你想要的功能都有. 下面进入正题. 由于JavaIO根据装饰器设计模式设计, 设计思想是先给出基本IO类,其他功能如缓存,格式化,再嵌套其他类实现. 在我看来实际上是个失败的设计,不仅没有使类变得简单,由于各种IO类必须组合起来才能发挥作用,反而增大了类的复杂度,写起来也冗余不已. 所以JavaIO类看起来会有些(非常)臃肿. 对于IO根据面向字符还是面向字节可分为两大类. 1. 面向字节的IO都是从InputStream和Ou

Java IO详解(一)------File 类

File 类:文件和目录路径名的抽象表示. 注意:File 类只能操作文件的属性,文件的内容是不能操作的. 1.File 类的字段 我们知道,各个平台之间的路径分隔符是不一样的. ①.对于UNIX平台,绝对路径名的前缀始终为"/" . 相对路径名没有前缀. 表示根目录的抽象路径名具有前缀"/"和空名称序列. ②.对于Microsoft Windows平台,包含驱动器说明符的路径名的前缀由后面跟着":"的驱动器号组成,如果路径名是绝对的,则可能后跟

标准文件IO详解(六)---fclose函数详解

fclose函数和close函数类似,用于关闭文件流指针.fclose函数被调用后,属于该文件流指针的用户缓冲区将会被强制刷新,并且对应的文件描述符 fd 也将会被关闭. ====================================================== 函数原型: 函数参数: fp:要关闭的文件流指针 返回值: 调用成功时返回 0 调用失败时返回 EOF

文件IO详解(六)---close函数详解

close函数用来在进程中关闭文件.当使用close关闭文件时,加在该文件上的所有的建议锁都将会被释放.内核中的文件表项也将会被释放. 函数原型: 函数参数: fd:要关闭文件的文件描述符 返回值: 调用成功返回 0 调用失败返回 -1,并修改errno的值

Java集合详解7:HashSet,TreeSet与LinkedHashSet

Java集合详解7:HashSet,TreeSet与LinkedHashSet 今天我们来探索一下HashSet,TreeSet与LinkedHashSet的基本原理与源码实现,由于这三个set都是基于之前文章的三个map进行实现的,所以推荐大家先看一下前面有关map的文章,结合使用味道更佳. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech 文章首发于我的个人博客: https://h2pl.github.io/2018/05/12/colle