hi I need to read byte arrays as an Object. however whenever I try it prints out Stream CorruptedException.

Below is my writing code

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!");
    }
}

then, this is read code

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();
    }
}

Then this is THE ERROR message I got.

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)

I can not understand what is wrong with this stream header. these are what I tried already :-<

  1. change List to Vector in writing code. (Serial problem)

Thanks for helping me :D

有帮助吗?

解决方案

I believe the problem lies in your storage and retrieval of the serialised bytes - the code to perform the serialisation and deserialisation is itself fine.

Without the intermediate storage, the code works, as shown below:

  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);

This produces:

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

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

You'll see that we find the beginning of the byte stream is ac ed 00 05 73, which are the following Java Object Serialization Specification constants:

  • STREAM_MAGIC
  • STREAM_VERSION
  • TC_OBJECT

As such, you investigation should focus on why your primal data doesn't match the originally generated data.


Let's continue in that direction (disclaimer: I've never used Redis) ...

You get the data back from Redis using this code:

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

Here, you get the data back as a Java String, and then get the bytes using the Java VM's default encoding scheme. This is potentially different to the encoding representation used by Redis.

Why don't you use the version that returns a byte[]? That would be:

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

This is likely to be consistent in any String to byte[] encoding and decoding.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top