2

我有一些不明白的地方,请帮忙。

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. 然后我想我的字节可能是无效的,所以我把每个字节都打印出来了,你可以看到,这四个字节都是有效的。

所以,我不知道为什么会这样。

请帮忙,非常感谢!

4

2 回答 2

5

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

但是,我的猜测是,您没有遵循 的规则ObjectInputStream,其中指定An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.

换句话说,为了实际使用 an 读取数据ObjectInputStream,您首先必须使用ObjectOutputStream某种类型的 an 写入数据。这是一个使用您提供的数据显示此内容的示例:

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,所以上面可能不是最佳实践或有多余的代码。)

于 2017-02-04T01:38:41.990 回答
1

available方法的javadoc,这就是它所说的:

返回可以在不阻塞的情况下读取的字节数。

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

现在,让我们看一下ObjectInputStream的 javadoc ,下面是简要说明:

超过分配数据结尾的非对象读取将反映数据的结尾,就像它们指示流的结尾一样:按字节读取将返回 -1 作为字节读取或读取的字节数,以及原始读取将抛出 EOFExceptions。如果没有对应的 writeObject 方法,则默认序列化数据的结尾标志着分配数据的结尾。

您在代码中尝试做的是read原始数据(或无WriteObject方法读取),因为它不是有效数据(for ObjectInputStreamread将始终返回-1。我能够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已写入对象并打印值。请注意,即使它正确读取对象并打印相同的对象,available方法仍然返回 0。因此,我建议不要过度依赖,available因为它的名称具有误导性 :)

于 2017-02-04T01:25:59.380 回答