3

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

5 Answers 5

6
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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer, I got it working using Base64 encoding now, although because I'm targeting Android < API v8, I had to use my own Base64 class, eg iharder.net/base64
3

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

Comments

1

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

Comments

1

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

1 Comment

This rocks. replacing my codes with <return bo.toString("ISO-8859-1");> & <byte b[] = str.getBytes("ISO-8859-1"); > did the trick.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.