ObjectOutputStream
类的对象用于序列化对象。ObjectInputStream
类的对象用于反序列化一个对象。ObjectOutputStream
继承自OutputStream
。ObjectInputStream
继承自InputStream
。
类必须实现Serializable
或Externalizable
接口以便序列化或反序列化。Serializable
接口是一个标记接口。如果想要一个Person
类的对象被序列化,需要声明Person
类如下:
public class Person implements Serializable {
}
Java负责处理从/向流读取/写入Serializable
对象的细节。只需要将对象传到流流类的write/read
方法之一。实现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
类如何序列化,它实现可序列化接口(Serializable
)。
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();
}
}
}
上面的代码生成以下结果。
Name: John, Gender: Male, Height: 1.7
Name: Wally, Gender: Male, Height: 1.7
Name: Katrina, Gender: Female, Height: 1.4
反序列化对象
以下代码显示如何创建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();
}
}
}
上面的代码生成以下结果。
Name: John, Gender: Male, Height: 6.7
Name: Wally, Gender: Male, Height: 5.7
Name: Katrina, Gender: Female, Height: 5.4
Name: John, Gender: Male, Height: NaN
Name: Wally, Gender: Male, Height: NaN
Name: Katrina, Gender: Female, Height: NaN
Objects were read from F:\website\yiibai\worksp\personext.ser