• I/O复习 三 ObjectInputSream/ObjectOutputStream


    对象持久化(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  " + Sid
    104                 + "  sex  " + Ssex;
    105     }
    106 }
    ObjectInputStream/ObjectOutputStream

    运行结果:

    已经将p和s对象写入到了 c:/data.dat
    Name  张三  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

     

  • 相关阅读:
    作为一名程序员应该具备哪些素质
    从100万个整数里找出100个最大的数
    数据库 SQL语句优化
    服务器上文件打包下载
    ThreadPoolExcutor
    几种序列化与get、set方法的关系
    idea没有错误出现红色波浪线怎么去掉?
    两个对象的属性赋值
    RandomStringUtils的使用
    IDEA中类似eclipse的workSpace的实现
  • 原文地址:https://www.cnblogs.com/mauiie/p/ObjectInputSream_ObjectOutputStream.html
Copyright © 2020-2023  润新知