Java序列化难题(java.io.StreamCorruptedException)

时间:2012-04-03 04:31:34

标签: java serialization

我尝试将对象序列化为Byte数组,以便存储在String中。我不能为我的生活找出我在这里出错的地方。

String store = null;

// Writing
try {
    String hi = "Hi there world!";
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(out);
    oos.writeObject(hi);
    oos.close();

    store = out.toString("UTF-8");
} catch(Exception e) {
    System.out.println(e);
}

// Reading
try {
    ByteArrayInputStream in = new ByteArrayInputStream(store.getBytes("UTF-8"));
    ObjectInputStream ois = new ObjectInputStream(in);

    String data = (String) ois.readObject();
} catch(Exception e) {
    System.out.println(e);
}

我一直在java.io.StreamCorruptedException,我不知道为什么:(

5 个答案:

答案 0 :(得分:6)

store = out.toString("UTF-8");

out中的数据不是UTF-8格式的,实际上它根本不是String。它是String的序列化实例。您可以在其上调用toString,因为您可以在任何对象上调用toString。

你想要

byte [] data = out.toByteArray();

然后将数据传递给ByteArrayInputStream构造函数

答案 1 :(得分:3)

不幸的是,Java字符串不是字节数组(如C中所示),而是字符数组(16位值)。此外,所有字符串都是Java中的unicode。

我最好的建议是:如果需要将二进制数据存储到字符串中,请使用Base64编码/解码。 Apache Commons为此任务提供了一些很棒的课程,您可以在以下网址找到更多信息:

http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html

答案 2 :(得分:1)

如果要将字节数组保存为字符串,则需要将其转换为Base64字符串,而不是UTF-8字符串。为此,您可以使用org.apache.commons.codec.binary.Base64

答案 3 :(得分:1)

我建议使用以下代码: 请注意,“ISO-8859-1”编码保留字节数组,而“UTF-8”不保留(某些字节数组导致此编码中的字符串无效)。

/**
 * Serialize any object
 * @param obj
 * @return
 */
public static String serialize(Object obj) {
    try {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream so = new ObjectOutputStream(bo);
        so.writeObject(obj);
        so.flush();
        // This encoding induces a bijection between byte[] and String (unlike UTF-8)
        return bo.toString("ISO-8859-1");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
/**
 * Deserialize any object
 * @param str
 * @param cls
 * @return
 */
public static <T> T deserialize(String str, Class<T> cls) {
    // deserialize the object
    try {
        // This encoding induces a bijection between byte[] and String (unlike UTF-8)
        byte b[] = str.getBytes("ISO-8859-1"); 
        ByteArrayInputStream bi = new ByteArrayInputStream(b);
        ObjectInputStream si = new ObjectInputStream(bi);
        return cls.cast(si.readObject());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

答案 4 :(得分:0)

问题是序列化时的初始字符串是序列化字符串。这与将字符串切割成其组成字符的数组不同。