嗨我需要将字节数组作为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;
感谢您帮助我:D
答案 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());
这可能在任何String
到byte[]
编码和解码中都是一致的。