为什么将字节数组读取到Object会抛出java.io.StreamCorruptedException?

Why reading byte array to an Object throws java.io.StreamCorruptedException?

我需要从远程系统中读取字节流。远程系统有自己的客户端API来读取字节。但在我最后,我必须将字节数组转换为POJO。在这样做的同时,我得到了错误java.io.StreamCorruptedException: invalid stream header:

为了测试功能,我编写了以下程序,将String转换为byte array,然后将字节数组转换为Object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class ByteToObject {
  public static void main(String[] args) {
    try {
      final String str ="Tiger";
      System.out.println("
Byte array for string '"
+ str +"' -->
"
+ Arrays.toString(getByteArray(str)));
      System.out.println("Object read -->" + getObject(getByteArray(str)));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static byte[] getByteArray(final String str) throws Exception {
    return str.getBytes(CharEncoding.UTF_8);
  }

  private static Object getObject(final byte[] byteArray) throws Exception {
    InputStream byteArrayStream = null;
    ObjectInputStream inputStream = null;

    try {
        byteArrayStream = new ByteArrayInputStream(byteArray);
        inputStream = new ObjectInputStream(byteArrayStream);
        return inputStream.readObject();
      } finally {
        if(null != byteArrayStream) {
          byteArrayStream.close();
        }
        if(null != inputStream) {
          inputStream.close();
        }
     }
  }
}

输出为:

1
2
3
4
5
6
7
8
Byte array for string 'Tiger' -->
[84, 105, 103, 101, 114]
java.io.StreamCorruptedException: invalid stream header: 54696765
Object read --> null
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
    at java.io.ObjectInputStream.(ObjectInputStream.java:299)
    at com.demo.serialize.ByteToObject.getObject(ByteToObject.java:41)
    at com.demo.serialize.ByteToObject.main(ByteToObject.java:24)

如果有人能帮上忙,你会感激吗?


因为你破坏了流。您不应该首先在String中拥有序列化数据。返回byte[]的往返行程有损。只需传递byte[]数组。

跟着我重复。String不是二进制数据的容器。写100次;-)

编辑0x54696765为"TIGE"。您最初没有序列化对象。你已经有了String

注意,如果你要关闭包装的ObjectInputStream,你不需要关闭ByteArrayInputStream,因为这只包装了ByteArrayInputStream,你也不需要关闭它。