开发者

What is wrong with my serialization mechanism?

开发者 https://www.devze.com 2023-01-20 10:43 出处:网络
This is the code which works fine on Mac OS (JDK 1.6): String s1 = \"test\"; ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());

This is the code which works fine on Mac OS (JDK 1.6):

String s1 = "test";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
String s2 = (String)(new ObjectInputStream(in).r开发者_开发知识库eadObject());

On linux CentOS 5.4 Java says:

java.io.StreamCorruptedException: invalid stream header: 3F3F0005
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
at com.XXX.SerializableTest.testWorks(SerializableTest.java:26)
[...]

What is it about?


ObjectInputStream only works on data written by ObjectOutputStream.

The getBytes() method of String isn't a Java Serialization mechanism; it merely encodes the character string using the default character encoding for your platform.


Using the no-argument getBytes() method is a bad idea for most applications. As I stated, it uses the default encoding for the platform it runs on. If the result will ever be used on a different machine, it is likely to break.

For most applications, you should explicitly specify the character encoding to be used.

It's important to keep in mind that some byte sequences are invalid in some character encodings. If you want to convert an arbitrary sequence of bytes to a character string, pick an encoding that assigns a single character to each byte value (if there is such a thing; the common ones I'm familiar with don't use every byte).

I'm guessing that, instead of "test", the string in question was created something like this:

ByteArrayOutputStream buf = ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(buf);
oos.writeObject(x);
oos.flush();
oos.close();
/* BAD! you should specify encoding! */
String encoded = new String(buf.toByteArray()); 

Instead, the last line should look like this, where encoding is a suitable character encoding, as discussed above:

String encoded = new String(buf.toByteArray(), encoding);

However, far better technique would be to use an encoding that was specifically designed for representing "binary" data as text. Base-64 is widely supported. Base-85 is more compact, but not as widespread. You'll need a third-party library to perform use one of these encodings. (Base-64 is implemented in the Sun [Oracle] run-time, but it's not part of the public API.)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号