Java Serialization Pains (java.io.StreamCorruptedException)

I am trying to Serialize an object into a byte array for storage in a String. I can't let my life determine me where I go wrong.

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

      

I keep getting java.io.StreamCorruptedException

and I don't know why :(

+3


source to share


5 answers


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

      

the data in out is not UTF-8 formatted, it is not actually a string. This is a serialized String instance. You can call toString on it, just because you can call toString on any object.

Do you want to



byte [] data = out.toByteArray ();

and then pass the data to the ByteArrayInputStream constructor

+6


source


Unfortunately, Java strings are not a byte array (as in C), but rather an array of characters (16-bit values). Also, all strings are unicode in Java.

My best advice: use Base64 encoding / decoding if you need to store binary data in strings. Apache Commons has some great classes for this task, and you can find more information at:



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

+3


source


If you want to store a byte array to a string, you need to convert it to a Base64 string, not a UTF-8 string. For this you can use org.apache.commons.codec.binary.Base64

+1


source


I would recommend the following code: Note that the "ISO-8859-1" encoding saves the byte array, while "UTF-8" does not work (some byte arrays result in invalid strings in this encoding).

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

      

+1


source


The problem is that the original string when serialized is a serialized string. This is not the same as chopping up a string into an array of its composite characters.

0


source







All Articles