而在Java中反序列化多个对象的条件

时间:2015-06-08 23:34:25

标签: java serialization

我目前正准备评估我的工作机会。因此,该公司已经给出了一些练习作业及其各自的解决方案。

我在如何从序列化文件中反序列化多个对象时遇到了一些困境。

最初,当我自己解决问题时,在研究了FileInputStream和ObjectInputStream的类定义之后,我认为最好的方法就是实现。

        FileInputStream fis = new FileInputStream(fileName);            
        ObjectInputStream ois = new ObjectInputStream(fis);
        while(fis.available()!=0)
        {
            obj = (Show)ois.readObject();
            lst.add(obj);
        }
        ois.close();
        fis.close();

但后来当我搜索时,我没有发现任何人建议这一点,虽然这对我来说很有效。 公司的转让解决方案是

         in=new ObjectInputStream(new FileInputStream(fileName));
         Show s=null;
         while((s=(Show)in.readObject())!=null){

            list.add(s);
         }  

但是当我尝试在另一个程序中使用后一种解决方案时,它给了我一个例外

        FileInputStream fis = new FileInputStream(fileNameChannel);
        ObjectInputStream ois = new ObjectInputStream(fis);

        while((obj=(Channel) ois.readObject())!=null){
            list.add(obj);
        }
        fis.close();
        ois.close();

例外:

java.io.EOFException
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at com.psl.util.SetTopBoxManagementSystemImpl.populateByChannelCategory(SetTopBoxManagementSystemImpl.java:29)
    at com.psl.main.Client.main(Client.java:18)

为了找到一个正确的答案,我尝试在StackExchange上搜索,发现人们实际上建议捕获异常并将其与使用While(true)结合使用。 - Link

我无法理解的是

  1. 为什么我不应该使用fis.available()> 0?或者更确切地说,为什么没有人?
  2. 同一实现导致一个程序中的EOFException而另一个程序中没有导致EOFException的可能原因是什么?由于两者都提取了序列化文件中存在的所有序列化对象。
  3. 为什么我应该考虑使用while(true)和捕获EOFException,如果我可以以一种方式实现,只要一切都好,就不会发生异常?这似乎是实现的捷径。如果出现问题(EOF明智),我们将如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

  1. readObject()在流结束时不返回null。它可以随时做到这一点。如果写入null,则返回null。所以你不能使用它。
  2. available() == 0不是对流结束的测试:请参阅Javadoc。所以你不能使用它。
  3. readObject()在流的末尾抛出EOFException。所以使用它。
  4. 回答你的问题:

      

    为什么我不应该使用fis.available()> 0?

    因为可以在不阻塞的情况下读取的字节数与流的结尾无关。

      

    或者更确切地说,为什么没有人?

    因为它不起作用。

      

    同一个实现导致一个程序中出现EOFException而另一个程序中出现EOFException的原因可能是什么?

    其中一个被发送一个null来表示流的结束。这是一种不好的做法,因为它可以防止你将null用于其他任何事情。需要带外值。实际上,尚不清楚null 是否意味着流的结尾。你可能会过早地停止阅读。

      

    为什么我应该考虑使用while(true)和捕获EOFException

    因为这就是API的设计方式。

      

    如果我能够以一种只要一切都好的话就不会发生异常的方式实施吗?

    但是一切都不会永远都好。您将获得截断文件,删除连接,...

      

    这似乎是实现目标的捷径。

    这没有意义。

      

    如果出现问题(EOF明智),我们将如何解决这个问题?

    抓住例外。