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 :(
source to share
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
source to share
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
source to share
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
source to share
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();
}
}
source to share