ByteArrayInputStream 到 ObjectInputStream 消失了
ByteArrayInputStream to ObjectInputStream disappeared
有不懂的地方,请大家帮忙
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之后,它变成了零。
我尝试过的事情:
- 起初,我怀疑我的字节数组是空的,但正如你所见,我打印出来,它的长度是 4。
- 然后我想我的字节可能是无效的,所以我把每个字节都打印出来,你可以看到,这四个字节都是有效的。
所以,我不知道为什么会这样。
请帮忙,非常感谢!
Here 是 available
方法的 javadoc,它是这样写的:
Returns the number of bytes that can be read without blocking.
因此,它不会 return 您 array/read 中存在的 bytes
总数,它 return 是 bytes
它可以在被封锁之前阅读。所以,它 returning 0 是一个有效的场景。
现在,让我们看一下ObjectInputStream的javadoc,这里是简要说明:
Non-object reads which exceed the end of the allotted data will
reflect the end of data in the same way that they would indicate the
end of the stream: bytewise reads will return -1 as the byte read or
number of bytes read, and primitive reads will throw EOFExceptions. If
there is no corresponding writeObject method, then the end of default
serialized data marks the end of the allotted data.
您在代码中尝试做的是 read
原始数据(或不使用 WriteObject
方法读取),因为它不是有效数据(对于 ObjectInputStream
) read
将始终 return -1。我能够通过调用 readObject
方法重现 EOFException
。
然后我尝试 writing/reading 一个新对象并测试了 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
方法仍然 returns 0。因此,我建议不要过分依赖 available
因为它是误导性名称:)
正如另一个答案提到的,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,因此以上内容可能不是最佳实践或有多余的代码。)
有不懂的地方,请大家帮忙
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之后,它变成了零。
我尝试过的事情:
- 起初,我怀疑我的字节数组是空的,但正如你所见,我打印出来,它的长度是 4。
- 然后我想我的字节可能是无效的,所以我把每个字节都打印出来,你可以看到,这四个字节都是有效的。
所以,我不知道为什么会这样。
请帮忙,非常感谢!
Here 是 available
方法的 javadoc,它是这样写的:
Returns the number of bytes that can be read without blocking.
因此,它不会 return 您 array/read 中存在的 bytes
总数,它 return 是 bytes
它可以在被封锁之前阅读。所以,它 returning 0 是一个有效的场景。
现在,让我们看一下ObjectInputStream的javadoc,这里是简要说明:
Non-object reads which exceed the end of the allotted data will reflect the end of data in the same way that they would indicate the end of the stream: bytewise reads will return -1 as the byte read or number of bytes read, and primitive reads will throw EOFExceptions. If there is no corresponding writeObject method, then the end of default serialized data marks the end of the allotted data.
您在代码中尝试做的是 read
原始数据(或不使用 WriteObject
方法读取),因为它不是有效数据(对于 ObjectInputStream
) read
将始终 return -1。我能够通过调用 readObject
方法重现 EOFException
。
然后我尝试 writing/reading 一个新对象并测试了 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
方法仍然 returns 0。因此,我建议不要过分依赖 available
因为它是误导性名称:)
正如另一个答案提到的,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,因此以上内容可能不是最佳实践或有多余的代码。)