【问题标题】:ObjectInputStream available() method doesn't work as expected (Java)ObjectInputStream available() 方法不能按预期工作(Java)
【发布时间】:2014-02-09 17:09:42
【问题描述】:

我一直试图弄清楚为什么我编写的从文件中读取对象的方法不起作用,并意识到即使文件没有完全读取,ObjectInputStream 的 available() 方法也会给出 0。 在我使用 FileInputStream available() 方法来确定 EOF 之后,该方法确实有效并且有效!

为什么该方法不适用于 ObjectInputSram 而适用于 FileInputStream?

代码如下:

public static void getArrFromFile() throws IOException, ClassNotFoundException {
    Product p;
    FileInputStream in= new FileInputStream(fName);
    ObjectInputStream input= new ObjectInputStream(in);
    while(in.available()>0){
        p=(Product)input.readObject();
        if (p.getPrice()>3000)
            System.out.println(p);
    }
    input.close();

P.S- 我读过我应该为此使用 EOF 异常而不是 available() ,但我只是想知道为什么这不起作用。

非常感谢!!!

【问题讨论】:

    标签: java


    【解决方案1】:

    因为,正如 javadoc 所说,available() 返回一个估计的可以读取的字节数没有阻塞。基本 InputStream 实现总是返回 0,因为这是一个有效的估计。但无论它返回什么,它返回 0 的事实并不意味着不再有任何可读取的内容。只是流不能保证至少可以读取一个字节而不阻塞。

    【讨论】:

    • 感谢您的回答,但我仍然看不出有什么区别。为什么该方法不适用于 ObjectInputSram 而适用于 FileInputStream?
    • 因为,出于某种原因,ObjectInputStream 不能保证(或选择不提供这样的保证)某些字节可以在没有阻塞的情况下读取,而 FileInputStream 可以。您必须深入研究这两个类的代码才能准确了解它们的 available() 类的作用。但这毫无用处,因为 available() 几乎从来没有用过,在这种情况下当然也没有。
    【解决方案2】:

    虽然这没有明确记录,但我从经验中意识到它与动态数据有关。如果你的类只包含静态类型的数据,那么available() 能够估计大小。如果您的对象中有动态数据,例如列表等,则无法进行该估计。

    【讨论】:

    • 欢迎来到 StackOverflow!请在问题下方提供 cmets,而不是直接回答。
    【解决方案3】:

    available() 方法只是告诉可以在不阻塞的情况下读取多少字节。它在常规代码中不是很有用,但人们看到这个名字并错误地认为它做了其他事情。

    简而言之:不要使用available(),这不是正确的使用方法。流表示不同的结束,例如返回 -1 或在 ObjectInputStream 的情况下,抛出 EOFException

    【讨论】:

      【解决方案4】:

      我发现了一些窍门!如果您仍想使用.available() 将所有对象读取到最后,您可以在写入文件并读取整数时在添加每个对象(例如:out.writeObject(obj))之前添加一个整数(例如:out.writeInt(0))在阅读每个对象之前。所以.available() 可以读取文件中留下的字节并且不会崩溃!希望对你有帮助!

      【讨论】:

        【解决方案5】:

        使用 InputStream 的可用函数而不是 ObjectInputStream。然后如果有任何数据,将它们作为对象获取。 比如:

        if(inputStreamObject.available() > 0){
         Object anyName =  objectInputStreamObject.readObject();
        }
        

        您可以直接从 Socket 中获取 inputStreamObject。 我用了,问题解决了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-15
          • 2016-01-16
          • 2020-09-14
          • 2013-09-21
          • 2012-07-24
          • 2015-06-26
          • 2013-05-28
          • 1970-01-01
          相关资源
          最近更新 更多