2021-04-18 11:17  阅读(90)
文章分类:Java 基础教程 文章标签:JavaJava 教程
©  原文作者:w3cschool 原文地址:https://www.w3cschool.cn/java/java-io-file.html

Java IO教程 - Java对象序列化

ObjectOutputStream类的一个对象用于序列化一个对象。

ObjectInputStream类的一个对象用于反序列化一个对象。

ObjectOutputStream继承自OutputStream。 ObjectInputStream继承自InputStream。

类必须实现Serializable或Externalizable接口以便序列化或反序列化。

Serializable接口是一个标记接口。

如果我们想要一个Person类的对象被序列化,我们需要声明Person类如下:

    public class Person   implements Serializable  {
        
    }
    

Java负责处理从/向流读取/写入Serializable对象的细节。我们只需要将对象写入/读取流到流类中的一个方法。

实现Externalizable接口使我们能够更好地控制从流中读取和写入对象。

它继承Serializable接口。它声明如下:

    public interface  Externalizable extends Serializable  {
        void  readExternal(ObjectInput in)  throws   IOException,  ClassNotFoundException;
        void  writeExternal(ObjectOutput out) throws   IOException;
    }
    

当我们从流中读取一个对象时,Java调用readExternal()方法。当我们向一个流写一个对象时,它调用writeExternal()方法。

我们必须编写逻辑来分别读取和写入readExternal()和writeExternal()方法中的对象的字段。

实现Externalizable接口的类如下所示:

    public class Person  implements Externalizable  {
        public void  readExternal(ObjectInput in)  throws   IOException,  ClassNotFoundException {
            // Write the logic to read the Person object fields  from  the   stream
        }    
        public void  writeExternal(ObjectOutput out) throws   IOException  {
            // Write  the   logic to write Person   object fields  to the   stream
        }
    }
    

序列化对象

以下代码创建ObjectOutputStream类的对象,并将对象保存到person.ser文件。

    ObjectOutputStream oos  = new ObjectOutputStream(new FileOutputStream("person.ser"));
    

要将对象保存到ByteArrayOutputStream,我们构造一个对象输出流如下:

    ByteArrayOutputStream baos  = new ByteArrayOutputStream();
    
    // Creates an  object output stream to write objects to the   byte   array  output stream
    ObjectOutputStream oos  = new ObjectOutputStream(baos);
    

使用ObjectOutputStream类的writeObject()方法通过将对象引用作为参数传递来序列化对象,如下所示:

    oos.writeObject(p1);
    

最后,当我们完成将所有对象写入时,使用close()方法关闭对象输出流:

    oos.close();
    

以下代码显示如何序列化实现可序列化接口的Person类。

    import java.io.Serializable;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    
    class Person implements Serializable {
      private String name = "Unknown";
      private String gender = "Unknown";
      private double height = Double.NaN;
    
      public Person(String name, String gender, double height) {
        this.name = name;
        this.gender = gender;
        this.height = height;
      }
    
      @Override
      public String toString() {
        return "Name: " + this.name + ", Gender:   " + this.gender + ",  Height: "
            + this.height;
      }
    }
    
    public class Main {
      public static void main(String[] args) {
        Person p1 = new Person("John", "Male", 1.7);
        Person p2 = new Person("Wally", "Male", 1.7);
        Person p3 = new Person("Katrina", "Female", 1.4);
    
        File fileObject = new File("person.ser");
    
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
            fileObject))) {
    
          oos.writeObject(p1);
          oos.writeObject(p2);
          oos.writeObject(p3);
    
          // Display the serialized objects on the standard output
          System.out.println(p1);
          System.out.println(p2);
          System.out.println(p3);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    

上面的代码生成以下结果。

20210418111119_1.png

反序列化对象

以下代码显示如何创建ObjectInputStream类的对象,并从person.ser文件读取对象。

    ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("person.ser"));
    

要从ByteArrayInputStream读取对象,请按如下所示创建对象输出流:

    ObjectInputStream ois  = new ObjectInputStream(Byte-Array-Input-Stream-Reference);
    

使用ObjectInputStream类的readObject()方法来反序列化对象。

    Object obj  = oos.readObject();
    

最后,关闭对象输入流如下:

    ois.close();
    

以下代码显示如何从文件读取对象。

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    public class Main {
      public static void main(String[] args) {
        File fileObject = new File("person.ser");
    
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
            fileObject))) {
    
          Person p1 = (Person) ois.readObject();
          Person p2 = (Person) ois.readObject();
          Person p3 = (Person) ois.readObject();
    
          System.out.println(p1);
          System.out.println(p2);
          System.out.println(p3);
    
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    

可外化对象序列化

要序列化和反序列化可外部化对象,请实现Externalizable接口。

    import java.io.Externalizable;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutput;
    import java.io.ObjectOutputStream;
    
    class PersonExt implements Externalizable {
      private String name = "Unknown";
      private String gender = "Unknown";
      private double height = Double.NaN;
    
      public PersonExt() {
      }
    
      public PersonExt(String name, String gender, double height) {
        this.name = name;
        this.gender = gender;
        this.height = height;
      }
      public String toString() {
        return "Name: " + this.name + ", Gender:   " + this.gender + ",  Height: "
            + this.height;
      }
    
      public void readExternal(ObjectInput in) throws IOException,
          ClassNotFoundException {
        this.name = in.readUTF();
        this.gender = in.readUTF();
      }
    
      public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(this.name);
        out.writeUTF(this.gender);
      }
    }
    
    
    
    public class Main {
      public static void main(String[] args) {
        PersonExt p1 = new PersonExt("John", "Male", 6.7);
        PersonExt p2 = new PersonExt("Wally", "Male", 5.7);
        PersonExt p3 = new PersonExt("Katrina", "Female", 5.4);
    
        File fileObject = new File("personext.ser");
    
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
            fileObject))) {
          oos.writeObject(p1);
          oos.writeObject(p2);
          oos.writeObject(p3);
    
          System.out.println(p1);
          System.out.println(p2);
          System.out.println(p3);
        } catch (IOException e1) {
          e1.printStackTrace();
        }
    
        fileObject = new File("personext.ser");
    
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
            fileObject))) {
    
          p1 = (PersonExt) ois.readObject();
          p2 = (PersonExt) ois.readObject();
          p3 = (PersonExt) ois.readObject();
    
          // Let"s display the objects that are read
          System.out.println(p1);
          System.out.println(p2);
          System.out.println(p3);
    
          // Print the input path
          System.out.println("Objects were  read   from  "
              + fileObject.getAbsolutePath());
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    

上面的代码生成以下结果。

2021041811113_2.png

点赞(0)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Java 对象序列化
上一篇
Java 管道
下一篇
Java 集合遍历