Java ObjectInputStream.read()返回-1,但readObject返回对象

Java ObjectInputStream.read()返回-1,但readObject返回对象,java,serialization,deserialization,ehcache,objectinputstream,Java,Serialization,Deserialization,Ehcache,Objectinputstream,我要序列化一个对象并反序列化该对象,但我得到: 0表示可用() -1用于读取() readByte()的EOFEException 这里我缺少什么?您正在调用可用,并在变量中的上读取,但在oin变量中读取对象 您正在调用可用,并在变量中的上读取,但在oin变量中调用readObject 我认为您看到这种行为是因为您首先从InputStream创建ObjectInputStream,然后在InputStream上选中available。如果您检查ObjectInputStream的构造函数,您可

我要序列化一个对象并反序列化该对象,但我得到:

  • 0表示可用()
  • -1用于读取()
  • readByte()的EOFEException


  • 这里我缺少什么?

    您正在调用
    可用,并在
    变量中的
    上读取
    ,但在
    oin
    变量中读取
    对象

    您正在调用
    可用,并在
    变量中的
    上读取
    ,但在
    oin
    变量中调用
    readObject

    我认为您看到这种行为是因为您首先从
    InputStream
    创建
    ObjectInputStream
    ,然后在
    InputStream
    上选中
    available
    。如果您检查
    ObjectInputStream
    的构造函数,您可以看到以下内容:

    public ObjectInputStream(InputStream in) throws IOException {
        verifySubclass();
        bin = new BlockDataInputStream(in);
        handles = new HandleTable(10);
        vlist = new ValidationList();
        enableOverride = false;
        readStreamHeader();
        bin.setBlockDataMode(true);
    } 
    

    有一个方法
    readStreamHeader
    从输入流中读取头。因此,在构建
    ObjectInputStream
    的过程中,所有数据都有可能从
    InputStream
    读取,我想您会看到这种行为,因为您首先从
    InputStream
    创建
    ObjectInputStream
    ,然后在
    InputStream
    上检查
    可用
    。如果您检查
    ObjectInputStream
    的构造函数,您可以看到以下内容:

    public ObjectInputStream(InputStream in) throws IOException {
        verifySubclass();
        bin = new BlockDataInputStream(in);
        handles = new HandleTable(10);
        vlist = new ValidationList();
        enableOverride = false;
        readStreamHeader();
        bin.setBlockDataMode(true);
    } 
    


    有一个方法
    readStreamHeader
    从输入流中读取头。因此,在构建
    ObjectInputStream

    的过程中,所有数据都可能从
    InputStream
    读取。有零个字节
    可用()
    read()
    返回-1表示EOS
    readLine()
    将返回null;而
    readXXX()
    也会对任何其他表示EOS的XXX抛出EOFEException;而
    readObject()
    返回一个
    对象
    ,因为您正在读取
    ObjectInputStream
    ,它是缓冲的,而不是调用所有其他方法的流。注意:你不应该仅仅为了测试EOS而调用
    read()
    ;而且
    available()
    首先不是对EOS的有效测试:请参阅Javadoc。

    您在流上的EOS,它告诉您这一点。有零个字节
    可用()
    read()
    返回-1表示EOS
    readLine()
    将返回null;而
    readXXX()
    也会对任何其他表示EOS的XXX抛出EOFEException;而
    readObject()
    返回一个
    对象
    ,因为您正在读取
    ObjectInputStream
    ,它是缓冲的,而不是调用所有其他方法的流。注意:你不应该仅仅为了测试EOS而调用
    read()
    ;而且
    available()
    首先不是EOS的有效测试:请参阅Javadoc。

    我已将
    available()
    read()
    更改为调用
    oin
    而不是
    中的
    。但是,结果是一样的。我将
    available()
    read()
    更改为调用
    oin
    ,而不是
    中的
    。但是,结果是一样的。我还使用
    available()
    &
    read()进行了测试
    ObjectInputStream
    而不是
    InputStream
    ,但结果是一样的。@JMOkomba在创建
    ObjectInputStream
    之前,您应该测试
    可用的
    读取的
    read
    可能会破坏流,因为
    ObjectInputStream
    不会获取此字节,并且无法解析对象。您是对的。如果我在创建
    ObjectInputStream
    之前调用
    available()
    read()
    ,它会给出结果,我也用
    available()
    read()进行了测试
    ObjectInputStream
    而不是
    InputStream
    ,但结果是一样的。@JMOkomba在创建
    ObjectInputStream
    之前,您应该测试
    可用的
    读取的
    read
    可能会破坏流,因为
    ObjectInputStream
    不会获取此字节,并且无法解析对象。您是对的。如果我在创建
    ObjectInputStream
    之前调用
    available()
    read()
    ,它会给出结果为什么
    available
    对EOS无效?那么什么是有效的呢?根据javadoc
    的规定,如果到达流的末尾,可用的
    应该返回0。@NikitaBeloglazov,因为它只告诉您可以在不阻塞的情况下读取多少字节。因此,返回值为零至少有两种含义。检测EOS的唯一方法是尝试阅读。我理解你的观点。但是javadoc for Returns说:
    可以从这个输入流中读取(或跳过)而不阻塞的字节数的估计值,或者当它到达输入流的末尾时为0。
    。所以当它到达终点时返回0。我觉得这很令人困惑。啊,好的。我明白了。我以前读它时就像“只有当它到达终点时才读0”。现在我明白了,它意味着更多的“当它到达终点时,它返回0”,不,“仅”。@NikitaBeloglazov它实际上意味着三件事,如果不是更多的话。1:如果不进行阻塞,就无法读取任何内容(但在这一点和流的结尾之间可能有TB);2:流结束;3:
    InputStream
    的此实现未实现
    available()
    (例如,从
    SSLSocket
    获取的输入流)。为什么
    available
    对EOS无效?那么什么是有效的呢?根据javadoc
    的规定,如果到达流的末尾,可用的
    应该返回0。@NikitaBeloglazov,因为它只告诉您可以在不阻塞的情况下读取多少字节。因此,零的返回值在lea处具有