反序列化在Java中

时间:2014-09-21 10:03:37

标签: java serialization deserialization

我使用多个对象序列化了一个文件。所以我写了一个如下代码 -

FileOutputStream outputStream=new FileOutputStream(new File("Output.ser"));
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(employee);
objectOutputStream.writeObject(employee2);
objectOutputStream.writeObject(employee3);
objectOutputStream.writeObject(employee4);
objectOutputStream.close();

现在我想对它进行反序列化,所以为了做到这一点,我借助WHILE循环来循环遍历所有对象!该守则如下所示 -

FileInputStream fileInputStream=new FileInputStream(new File(fileName));
ObjectInputStream stream=new ObjectInputStream(fileInputStream);
Employee emp;
while((emp=(Employee) stream.readObject())!=null)
{
    String uName=emp.getUserId();
    String uPass=emp.getPassword();
    map.put(uName, uPass);
}

此代码使EOFException到达文件末尾。我猜readObject()应该在到达文件末尾时返回null,但在这种情况下它最终抛出异常! 请建议我成功阅读序列化文件的方式,而不会出现任何异常!

3 个答案:

答案 0 :(得分:2)

您应该序列化List,而不是序列化多个对象:

FileOutputStream outputStream=new FileOutputStream(new File("Output.ser"));
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
ArrayList<Employee> employees = new ArrayList<Employee>();
employees.add(employee);
employees.add(employee2);
employees.add(employee3);
employees.add(employee4);
objectOutputStream.writeObject(employees);
objectOutputStream.close();

您可以这样反序列化:

FileInputStream fileInputStream=new FileInputStream(new File(fileName));
ObjectInputStream stream=new ObjectInputStream(fileInputStream);
for(Employee emp : (ArrayList)stream.readObject())
{
    String uName = emp.getUserId();
    String uPass = emp.getPassword();
    map.put(uName, uPass);
}

答案 1 :(得分:1)

当您到达文件结尾时,stream.readObject()将不会返回null。它会抛出EOFExcpetion来表示。

您的读取次数应与写入次数基本匹配。如果您在循环中readObject,则会面对EOFException

您拥有的选项是:

  1. 通过在所写对象数量上保留一个标签,与readObject次调用进行尽可能多的writeObject次调用。

  2. 按照@Richard的说法存储在列表中,然后拨打readObject一次。

  3. 在您发布的实施句柄EOFException中,执行文件结束时您需要执行的操作并关闭该流。

答案 2 :(得分:0)

我更愿意使用Collection Framework(例如ArrayList)或任何其他可以在序列化多个对象时封装许多对象的对象。
但要按照自己的方式工作,您必须为序列化文件提供标准。您可以将第一个对象添加为Integer,它将告诉您文件中存储了多少对象。

FileOutputStream outputStream=new FileOutputStream(new File("Output.ser"));
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(new Integer(4));
objectOutputStream.writeObject(employee);
objectOutputStream.writeObject(employee2);
objectOutputStream.writeObject(employee3);
objectOutputStream.writeObject(employee4);
objectOutputStream.close();

在绝望时,您可以获得序列化的对象数量。

FileInputStream fileInputStream=new FileInputStream(new File(fileName));
ObjectInputStream stream=new ObjectInputStream(fileInputStream);
Employee emp;
Integer size = (Integer) stream.readObject();
for(int i = 0; i < size; i++) {
    Employee emp = (Employee) stream.readObject();
    String uName=emp.getUserId();
    String uPass=emp.getPassword();
    map.put(uName, uPass);
}

这是一种常规方法,在您的文件系统中存储了多少文件,但是您可以在外部为自己的目的进行操作。请记住,如果您决定以这种方式工作,则必须进行必要的异常处理。