readObject时发生StreamCorrupedException

时间:2014-03-19 09:06:18

标签: java exception header stream redis

嗨我需要将字节数组作为Object读取。但每当我尝试打印出Stream CorruptedException。

以下是我的写作代码

public class TestSave {
    public static void main(String[] args) {
        String key = "redismap";
        Map<String, Object> map = new HashMap<String, Object>();
        List<String> list = new ArrayList<String>();

        map.put("String", "test");
        map.put("List", list);

        ObjectOutputStream oos = null;
        ByteArrayOutputStream bos = null;

        JedisHelper helper = JedisHelper.getInstacne();
        Jedis connection = helper.getConnection();

        try{
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(map);
            byte[] value = bos.toByteArray();           
            oos.close();
            connection.set(key.getBytes(), value);
        }catch(Exception e){e.printStackTrace();}
        helper.returnResource(connection);
        helper.destroyPool();
        System.out.println("DONE!");
    }
}

然后,这是读取代码

public class TestWithdaw {
    public static void main(String[] args) {
        JedisHelper helper = JedisHelper.getInstacne();
        Jedis connection = helper.getConnection();
        String key = "redismap";
        String result = connection.get(key);
        byte[] primalData = result.getBytes();
        System.out.println("Byte Arrays : " + Arrays.toString(primalData));

        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try{
            bis = new ByteArrayInputStream(primalData);
            ois = new ObjectInputStream(bis);
            Object resultMap = ois.readObject();

            System.out.println("resultMap : " + resultMap);
            ois.close();
        }catch(Exception e){e.printStackTrace();}
        helper.returnResource(connection);
        helper.destroyPool();
    }
}

然后这是我收到的错误信息。

java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
    at org.owls.redis.test.TestWithdaw.main(TestWithdaw.java:28)

我无法理解此流标头有什么问题。 这些是我已经尝试过的: - &lt;

  1. 在编写代码时将List更改为Vector。 (系列问题)
  2. 感谢您帮助我:D

1 个答案:

答案 0 :(得分:2)

我认为问题在于存储和检索序列化字节 - 执行序列化和反序列化的代码本身就很好。

没有中间存储,代码可以正常工作,如下所示:

  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  ObjectOutputStream oos = new ObjectOutputStream(bos);
  oos.writeObject(map);
  byte[] value = bos.toByteArray();
  oos.close();

  for (byte b : value)
  {
    System.out.print(Integer.toHexString(0xff & b) + " ");
  }
  System.out.println("");

  final ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(value));
  final Object read = ois.readObject();

  System.out.println("read: " + read);

这会产生:

  

ac ed 0 5 73 72 0 11 6a 61 76 61 2e 75 74 69 6c 2e 48 61 73 68 4d 61 70 5 7 da c1 c3 16 60 d1 3 0 2 46 0 a 6c 6f 61 64 46 61 63 74 6f 72 49 0 9 74 68 72 65 73 68 6f 6c 64 78 70 3f 40 0 0 0 0 0 c 77 8 0 0 0 10 0 0 0 2 74 0 6 53 74 72 69 6e 67 74 0 4 74 65 73 74 74 0 4 4c 69 73 74 73 72 0 13 6a 61 76 61 2e 75 74 69 6c 2e 41 72 72 61 79 4c 69 73 74 78 81 d2 1d 99 c7 61 9d 3 0 1 49 0 4 73 69 7a 65 78 70 0 0 0 0 77 4 0 0 0 0 78 78

     

读:{List = [],String = test}

您将看到我们发现字节流的开头是ac ed 00 05 73,它们是以下Java对象序列化规范常量:

  • STREAM_MAGIC
  • STREAM_VERSION
  • TC_OBJECT

因此,您应该关注原始数据与最初生成的数据不匹配的原因。


让我们继续这个方向(免责声明:我从未使用过Redis)......

您可以使用以下代码从Redis获取数据:

String key = "redismap";
String result = connection.get(key);
byte[] primalData = result.getBytes();

在这里,您将数据作为Java String返回,然后使用Java VM的默认编码方案获取字节。这可能与Redis使用的编码表示不同。

为什么不使用返回byte[]的版本?那将是:

String key = "redismap";
byte[] primalData = connection.get(key.getBytes());

这可能在任何Stringbyte[]编码和解码中都是一致的。