aaronsnoswell
aaronsnoswell

Reputation: 6251

Java Serialization Pains (java.io.StreamCorruptedException)

I'm trying to Serialize an object to a Byte array, for storage in a String. I cannot for the life of me figure out where I'm going wrong here.

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 :(

Upvotes: 3

Views: 2481

Answers (5)

ngrislain
ngrislain

Reputation: 1072

I would recommend the following code: Note that the "ISO-8859-1" encoding preserves a byte array, while "UTF-8" does not (some bytes array lead to 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();
    }
}

Upvotes: 1

Eugene Retunsky
Eugene Retunsky

Reputation: 13139

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

Upvotes: 1

Tommy B
Tommy B

Reputation: 185

The problem is that the initial string when serialized is a serialized String. That's not the same as chopping the string into an array of its constituent characters.

Upvotes: 0

Robson Fran&#231;a
Robson Fran&#231;a

Reputation: 661

Unfortunatelly, Java strings aren't an array of bytes (as in C), but rather an array of chars (16-bit values). Also, all strings are unicode in Java.

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

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

Upvotes: 3

MeBigFatGuy
MeBigFatGuy

Reputation: 28568

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

the data in out is not UTF-8 formatted, in fact it's not a String at all. It's a serialized instance of a String. You can call toString on it, just because you can call toString on any object.

you'd want to to

byte[] data = out.toByteArray();

and then pass data into the ByteArrayInputStream constructor

Upvotes: 6

Related Questions