博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
I/O复习 三 ObjectInputSream/ObjectOutputStream
阅读量:6174 次
发布时间:2019-06-21

本文共 5118 字,大约阅读时间需要 17 分钟。

对象持久化(Persistence)就是 将对象保存到磁盘文件或者网络中,保存对象的过程实质上就是对象持久化的过程。

* 也就是记录对象的状态以便于将来具有再生的能力。 Java提供了对象流以实现对象的输入输出,也就是实现对象的持久化。
* 需要注意的是在使用对象流之前必须要将该对象序列化。所谓的序列化就是将对象的状态转化成字节流,并且以后可以通过这些值 再生成相同状态的对象。
* 简单来说序列化就是一种用来处理对象流的机制,而对象流也就是将对象的内容进行流化,我们可以对流化后的对象进行读取操作,
* 也可以将流化后的对象传输于网络之间。
*
* 对象序列化,只需要被序列化的类实现Serializable接口就可以了。
* Serializable接口中没有任何的方法,让一个类实现该接口只是为了标注该对象是可以被序列化的,然后就可以对该对象进行持久化。
*
* 注意: 序列化只能保存对象的实例变量,但不能保存类的任何方法和类变量,并且保存的只是变量的值。 对于任何修饰符都不能保存。
* 有些类型的变量是瞬时的,这样的对象也是无法保存的,如:线程对象、或流对象。对于这样的变量,必须用transient关键字标明,否则编译器将报错。
*
* 任何被transient标明的成员变量,将不被保存。
* 考虑到序列化可能涉及对象保存在磁盘上或者网络上,对于一些保密的数据就要加上transient关键字。
*
*
* 对象序列化之后,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象的状态保存下来,再通过对象输入流将对象的状态恢复。
* java提供了ObjectInputStream
* 类和ObjectOutputStream类分别实现了ObjectInput和ObjectOutput。
* ObjectOutput接口用writeObject
* ()方法,可以将对象的状态保存到输出流中。而ObjectInput接口用readObject()方法以从输入流中读入一个对象。
*

 

Demo:

1 package com.tai.io;  2   3 import java.io.FileInputStream;  4 import java.io.FileNotFoundException;  5 import java.io.FileOutputStream;  6 import java.io.ObjectInputStream;  7 import java.io.ObjectOutputStream;  8 import java.io.Serializable;  9  10 public class PersistenceDome 11 { 12     /** 13      * 对象持久化(Persistence)就是 将对象保存到磁盘文件或者网络中,保存对象的过程实质上就是对象持久化的过程。 14      * 也就是记录对象的状态以便于将来具有再生的能力。 Java提供了对象流以实现对象的输入输出,也就是实现对象的持久化。 15      * 需要注意的是在使用对象流之前必须要将该对象序列化。所谓的序列化就是将对象的状态转化成字节流,并且以后可以通过这些值 再生成相同状态的对象。 16      * 简单来说序列化就是一种用来处理对象流的机制,而对象流也就是将对象的内容进行流化,我们可以对流化后的对象进行读取操作, 17      * 也可以将流化后的对象传输于网络之间。 18      *  19      * 对象序列化,只需要被序列化的类实现Serializable接口就可以了。 20      * Serializable接口中没有任何的方法,让一个类实现该接口只是为了标注该对象是可以被序列化的,然后就可以对该对象进行持久化。 21      *  22      * 注意: 序列化只能保存对象的实例变量,但不能保存类的任何方法和类变量,并且保存的只是变量的值。 对于任何修饰符都不能保存。 23      * 有些类型的变量是瞬时的,这样的对象也是无法保存的,如:线程对象、或流对象。对于这样的变量,必须用transient关键字标明,否则编译器将报错。 24      *  25      * 任何被transient标明的成员变量,将不被保存。 26      * 考虑到序列化可能涉及对象保存在磁盘上或者网络上,对于一些保密的数据就要加上transient关键字。 27      *  28      *  29      * 对象序列化之后,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象的状态保存下来,再通过对象输入流将对象的状态恢复。 30      * java提供了ObjectInputStream 31      * 类和ObjectOutputStream类分别实现了ObjectInput和ObjectOutput。 32      * ObjectOutput接口用writeObject 33      * ()方法,可以将对象的状态保存到输出流中。而ObjectInput接口用readObject()方法以从输入流中读入一个对象。 34      *  35      * @throws Exception 36      */ 37     public static void main(String[] args) throws Exception 38     { 39         Person p = new Person("张三", "Mauiie", "男"); 40         Person p2 = new Person("p2", "Mauiie", "男"); 41         Person p3 = new Person("p3", "Mauiie", "男"); 42         Student s = new Student("孙俪", "Mauiie", "女"); 43         Person temp = null; 44         Person temp2 = null; 45         Student stemp = null; 46         FileOutputStream fos = new FileOutputStream("c:/data.dat"); 47         ObjectOutputStream oos = new ObjectOutputStream(fos); 48         oos.writeObject(p); 49         oos.writeObject(p2); 50 //        oos.writeObject(p3); 51         oos.writeObject(s); 52         oos.close(); 53         System.out.println("已经将p和s对象写入到了 c:/data.dat"); 54  55         FileInputStream fis = new FileInputStream("c:/data.dat"); 56         ObjectInputStream ois = new ObjectInputStream(fis); 57  58         temp = (Person) ois.readObject(); 59         temp2 = (Person) ois.readObject(); 60         stemp = (Student) ois.readObject(); 61          62         ois.close(); 63         System.out.println(temp.toString()); 64         System.out.println(stemp.toString()); 65         System.out.println(temp2.toString()); 66     } 67 } 68  69 class Person implements Serializable 70 { 71     String Pname; 72     transient String Pid; 73     String Psex; 74  75     public Person(String name, String ID, String sex) 76     { 77         this.Pname = name; 78         this.Pid = ID; 79         this.Psex = sex; 80     } 81  82     public String toString() 83     { 84         return "Name  " + Pname + "  ID  " + Pid + "  sex  " + Psex; 85     } 86 } 87  88 class Student implements Serializable 89 { 90     String Sname; 91     transient String Sid; 92     String Ssex; 93  94     public Student(String name, String ID, String sex) 95     { 96         this.Sname = name; 97         this.Sid = ID; 98         this.Ssex = sex; 99     }100 101     public String toString()102     {103         return "这是Student对象      " + "Name  " + Sname + "  ID  " + Sid104                 + "  sex  " + Ssex;105     }106 }
ObjectInputStream/ObjectOutputStream

运行结果:

已经将p和s对象写入到了 c:/data.datName  张三  ID  null  sex  男这是Student对象      Name  孙俪  ID  null  sex  女Name  p2  ID  null  sex  男

 

值得注意的是:

使用缺省的serializetion的实现时,一个ObjectOutputStream的构造和一个ObjectInputStream的构造必须一一对应。

ObjectOutputStream的构造函数会向输出流中写入一个标识头,而ObjectInputStream会首先读入这个标识头。因此,多次以追加方式向一个文件中写入object时,该文件将会包含多个标识头。

所以用ObjectInputStream来deserialize这个ObjectOutputStream时,将产生StreamCorruptedException。

一种解决方法是可以构造一个ObjectOutputStream的子类,并覆盖writeStreamHeader()方法。被覆盖后的writeStreamHeader()方法应判断是否为首次向文件中写入object?

若是,则调用super.writeStreamHeader();若否,即以追加方式写入object时,则应调用ObjectOutputStream.reset()方法。

 

如果再向该文件增加对象,新写的对象就读不出了可以参照下面这篇博客,我也遇到这样的问题, 我看了之后也觉得十分受教

http://halzhang.iteye.com/blog/267917

 

 

 

 

 

转载于:https://www.cnblogs.com/mauiie/p/ObjectInputSream_ObjectOutputStream.html

你可能感兴趣的文章
中使馆驳斥《金融时报》“中国网络威胁论”
查看>>
【挨踢人物传】茶乡浪子:“传奇”职场路,一生感谢情(第12期)
查看>>
我的友情链接
查看>>
c#关于数据库连接操作的案例
查看>>
聊聊最近接触的媒体查询!
查看>>
HAproxy指南之haproxy重定向应用(案例篇)
查看>>
学习 HTTP协议挺不错的一个类
查看>>
深入字节码 -- ASM 关键接口 MethodVisitor
查看>>
linux 文件权限
查看>>
Linux常用命令集合
查看>>
Oracle DML
查看>>
Linux - FHS文件系统层次标准
查看>>
报错:Invalid bound statement (not found)
查看>>
Linux GPT分区格式磁盘的相关操作
查看>>
通过Docker进程pid获取容器id
查看>>
L15.2 zabbix基础(2)组件说明介绍
查看>>
impdp 常见问题 10g/11g/12c 问题解决 ERIKXUE
查看>>
2013年1月工作小结 -- 上线后的懈怠
查看>>
敏捷宣言
查看>>
php Yii: 出现undefined offset 或者 undefined index解决方案
查看>>