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&aposs 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