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

时间:2013-02-18 07:48:45

标签: java serialization deserialization ehcache objectinputstream

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

  1. 0 for available()
  2. -1 for read()
  3. readByte()

    的EOFException
    public static Element getCacheObject(String key, String cacheName, String server) throws IOException, ClassNotFoundException, ConnectException {
        String url = StringUtils.join(new String[] { server, cacheName, key}, "/");
        GetMethod getMethod = new GetMethod(url);
        ObjectInputStream oin = null;
        InputStream in = null;
        int status = -1;
        Element element = null;
        try {
            status = httpClient.executeMethod(getMethod);
            if (status == HttpStatus.SC_NOT_FOUND) { // if the content is deleted already               
                return null;
            }
            in = getMethod.getResponseBodyAsStream();
            oin = new ObjectInputStream(in);
            System.out.println("oin.available():" + oin.available()); // returns 0
            System.out.println("oin.read():" + oin.read()); // returns -1
            element = (Element) oin.readObject(); // returns the object
        }
        catch (Exception except) {
            except.printStackTrace();
            throw except;
        }
        finally {
            try {
                oin.close();
                in.close();
            }
            catch (Exception except) {
                except.printStackTrace();
            }
        }
    
        return element;
    }
    
  4. 我在这里缺少什么?

3 个答案:

答案 0 :(得分:1)

我认为您会看到此行为,因为您首先从ObjectInputStream创建InputStream,然后在available上查看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从输入流中读取标头。因此,在构建InputStream期间,可能会从ObjectInputStream读取所有数据。

答案 1 :(得分:0)

您在available and read变量上调用了in,但在readObject变量上调用了oin

答案 2 :(得分:0)

您正在流媒体上的EOS告诉您。无阻塞地读取零字节available(); read()返回-1表示EOS; readLine()将返回null;并且readXXX()也会对指示EOS的任何其他XXX抛出EOFException;并且readObject()会返回Object,因为您正在阅读缓存的ObjectInputStream,而不是您调用所有其他方法的流。注意,您不应该仅仅为了测试EOS而致电read();并且available()首先不是EOS的有效测试:请参阅Javadoc。