Java IO:ObjectInputStream

时间:2020-01-09 10:36:04  来源:igfitidea点击:

Java ObjectInputStream类(java.io.ObjectInputStream)使我们可以从InputStream读取Java对象,而不仅仅是原始字节。我们将一个InputStream封装在ObjectInputStream中,然后可以从中读取对象。当然,读取的字节必须表示一个有效的序列化Java对象。否则,读取对象将失败。

通常,我们将使用ObjectInputStream读取由Java ObjectOutputStream编写(序列化)的对象。稍后我们将看到一个示例。

ObjectInputStream示例

这是一个JavaObjectInputStream示例:

ObjectInputStream objectInputStream =
    new ObjectInputStream(new FileInputStream("object.data"));

MyClass object = (MyClass) objectInputStream.readObject();
//etc.

objectInputStream.close();

为了使这个" ObjectInputStream"示例正常工作,我们读取的对象必须是" MyClass"的实例,并且必须已通过" ObjectOutputStream"序列化到文件" object.data"中。

在可以序列化和反序列化对象之前,对象的类必须实现java.io.Serializable。有关更多信息,请参见Java Serializable。

将ObjectInputStream与ObjectOutputStream一起使用

我之前曾承诺向我们展示一个将JavaObjectInputStreamObjectOutputStream结合使用的示例。这是一个例子:

import java.io.*;

public class ObjectInputStreamExample {

    public static class Person implements Serializable {
        public String name = null;
        public int    age  =   0;
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        ObjectOutputStream objectOutputStream =
            new ObjectOutputStream(new FileOutputStream("data/person.bin"));

        Person person = new Person();
        person.name = "Hyman";
        person.age  = 40;

        objectOutputStream.writeObject(person);
        objectOutputStream.close();

        ObjectInputStream objectInputStream =
            new ObjectInputStream(new FileInputStream("data/person.bin"));

        Person personRead = (Person) objectInputStream.readObject();

        objectInputStream.close();

        System.out.println(personRead.name);
        System.out.println(personRead.age);
    }
}

这个例子首先创建一个连接到FileOutputStream的ObjectOutputStream。然后,它创建一个" Person"对象并将其写入" ObjectOutputStream",然后关闭" ObjectOutputStream"。

然后,该示例创建一个" ObjectInputStream",该对象连接到" ObjectOutputStream"所连接到的同一文件。然后,该示例从ObjectInputStream中读取一个对象,并将其强制转换为Person对象。之后,也关闭了" ObjectInputStream",并将读入" Person"对象的值打印到" System.out"。

运行此示例输出的输出应为:

Hyman
40

关闭一个ObjectInputStream

从ObjectInputStream读取完数据后,我们应该记住将其关闭。关闭ObjectInputStream也会关闭从中读取ObjectInputStream的InputStream实例。

通过调用对象的close()方法来关闭对象输入流。这是关闭ObjectInputStream的样子:

objectInputStream.close();

我们还可以使用Java 7中引入的try-with-resources构造。这是如何使用try-with-resources构造使用和关闭" ObjectInputStream"外观的方法:

InputStream input = new FileInputStream("data/data.bin");

try(ObjectInputStream objectInputStream =
    new ObjectInputStream(input)){

    Person personRead = (Person) objectInputStream.readObject();
}

请注意,不再有任何显式的close()方法调用。 try-with-resources构造可以解决这一问题。

还要注意,没有在try-with-resources块内创建第一个FileInputStream实例。这意味着try-with-resources块不会自动关闭此FileInputStream实例。但是,当关闭" ObjectInputStream"时,也会关闭其读取的" InputStream"实例,因此当" ObjectInputStream"关闭时," FileInputStream"实例也将关闭。