ByteArrayInputStream到ObjectInputStream消失了

时间:2017-02-04 00:55:35

标签: java io objectinputstream bytearrayinputstream

我有些事我不明白,请帮助。

System.out.println("\n" + Arrays.toString(buffer) + "\n");
System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available());
ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(buffer));
System.out.println("input.available(): " + input.available());

其输出如下:

[-84, -19, 0, 5]

buffer.length = 4
new ByteArrayInputStream(buffer).available() is: 4
input.available(): 0

我很困惑为什么4个有效字节的字节数组在放入ObjectInputStream后变为零。

我尝试过的事情:

  1. 最初,我怀疑我的字节数组是空的,但是如你所见,我打印出来,它的长度是4。
  2. 然后我认为我的字节可能无效,所以我打印出每个字节,如你所见,这四个字节都是有效的。
  3. 所以,我迷失了为什么会这样。

    请帮助,非常感谢!

2 个答案:

答案 0 :(得分:3)

正如提到的另一个答案,available仅表示阻止发生之前可以读取的字节数。

然而,我猜你没有遵守指定ObjectInputStream

An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.规则

换句话说,为了使用ObjectInputStream实际读取数据,您首先必须使用某种ObjectOutputStream编写数据。以下是使用您提供的数据显示此示例的示例:

byte[] buffer = new byte[]{-84,-19,0,5};
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream= new ObjectOutputStream(out);
objectOutputStream.write(buffer);
objectOutputStream.flush();

ObjectInput input = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
System.out.println("input.available(): " + input.available());
System.out.println("input.readByte(): " + input.readByte());

(我要补充一点,我很少在Java中使用IO,所以上面的内容可能不是最佳实践,也不是多余的代码。)

答案 1 :(得分:1)

Hereavailable方法的javadoc,它就是这样说的:

  

返回可以不阻塞地读取的字节数。

因此,它不会返回数组/读取中存在的bytes总数,它会在被阻止之前返回它可以读取的bytes个数。因此,它返回0是一个有效的场景。

现在,让我们看一下ObjectInputStream的javadoc,这里有一个简短的解释:

  

超出分配数据末尾的非对象读取将会   以与他们指示数据相同的方式反映数据的结尾   流结束:逐字节读取将返回-1作为字节读取或   读取的字节数,原始读取将抛出EOFExceptions。如果   没有相应的writeObject方法,那么默认结束   序列化数据标志着分配数据的结束。

您在代码中尝试执行的操作是read原始数据(或不使用WriteObject方法读取),因为它不是有效数据(对于ObjectInputStream){{ 1}}将始终返回-1。我只需调用read方法即可重现EOFException

然后我尝试编写/阅读新对象并测试了readObject方法调用,请看下面的代码段:

available

代码byte[] buffer = new byte[]{-84, -19, 0, 5}; System.out.println("\n" + Arrays.toString(buffer) + "\n"); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer); System.out.println("buffer.length = " + buffer.length + "\nnew ByteArrayInputStream(buffer).available() is: " + new ByteArrayInputStream(buffer).available()); ObjectInputStream input = new ObjectInputStream(byteArrayInputStream); System.out.println("input.available(): " + input.available()); // System.out.println(input.readObject()); //Uncomment to see EOFException Date date = new Date(); System.out.println(date); ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteArrayOut); out.writeObject(date); byte[] bytes = byteArrayOut.toByteArray(); input = new ObjectInputStream(new ByteArrayInputStream(bytes)); System.out.println(input.available()); System.out.println(input.readObject()); 已写入的对象并打印该值。请注意,即使它正确读取对象并打印相同的对象,reads方法仍会返回0.因此,我建议不要过分依赖available,因为它具有误导性名称:)