StreamCorrupedException возникает, когда readObject

1

hi Мне нужно прочитать байтовые массивы как объект. однако всякий раз, когда я пытаюсь, он выдает 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();
    }
}

Тогда это сообщение ERROR, которое я получил.

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)

Я не могу понять, что не так с этим заголовком потока. это то, что я уже пробовал: - <

  1. изменить список на Vector в письменном коде. (Последовательная проблема)

Спасибо, что помогли мне: D

Теги:
exception
redis
header
stream

1 ответ

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

read: {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();

Здесь вы возвращаете данные в виде String Java, а затем получаете байты с использованием схемы кодирования по умолчанию Java VM. Это потенциально отличается от представления кодировки, используемого Redis.

Почему вы не используете версию, которая возвращает byte[]? Это было бы:

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

Вероятно, это будет согласовано в любой кодировке и декодировании String to byte[].

  • 0
    Большое спасибо. На самом деле, я беспокоюсь о кодировке символов набора ключей. Однако после того, как я изменил параметр с String на byte [], как вы предложили, он прекрасно работает. Еще раз спасибо: D
  • 0
    @greg Аналогичная ситуация произошла с нами, когда мы использовали кодировку ISO-8859-1 с хранилищем данных Redis. Наконец все преобразовано в byte [] и теперь все работает нормально. Спасибо, ваш ответ дал мне несколько советов для отладки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню