- public class TestDeserialize extends TestCase {
- public void testDeserialize() throws IOException, ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- BigInteger bi = new BigInteger("0");
- oos.writeObject(bi);
- String str = baos.toString();
- System.out.println(str);
- ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(str.getBytes())));
- Object obj = ois.readObject();
- }
- }
抛出错误
- [junit] ------------- ---------------- ---------------
- [junit] Testcase: testDeserialize(org.jboss.remoting.loading.TestDeserialize): Caused an ERROR
- [junit] invalid stream header: EFBFBDEF
- [junit] java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
- [junit] at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:783)
- [junit] at java.io.ObjectInputStream.<init>(ObjectInputStream.java:280)
- [junit] at org.jboss.remoting.loading.TestDeserialize.testDeserialize(TestDeserialize.java:20)
- [junit]
- [junit]
- [junit] Test org.jboss.remoting.loading.TestDeserialize FAILED
修改成为
- public void testDeserialize() throws IOException, ClassNotFoundException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- BigInteger bi = new BigInteger("0");
- oos.writeObject(bi);
- byte[] str = baos.toByteArray();
- ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(str)));
- Object obj = ois.readObject();
- assertNotNull(obj);
- assertEquals(obj.getClass().getName(),"java.math.BigInteger");
- assertEquals(((BigInteger)obj).intValue(), 0);
- }
搞定,原因请见
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4968673
The provided test code serializes an object to a ByteArrayOutputStream, converts the generated byte array into a string using the ByteArrayOutputStream.toString() method, converts the string back into a byte array using the String.getBytes() method, and then attempts to deserialize the object from the byte array using a ByteArrayInputStream. This procedure will in most cases fail because of the transformations that take place within ByteArrayOutputStream.toString() and String.getBytes(): in order to convert the contained sequence of bytes into a string, ByteArrayOutputStream.toString() decodes the bytes according to the default charset in effect; similarly, in order to convert the string back into a sequence of bytes, String.getBytes() encodes the characters according to the default charset. Converting bytes into characters and back again according to a given charset is generally not an identity-preserving operation. As the javadoc for the String(byte[], int, int) constructor (which is called by ByteArrayOutputStream.toString()) states, "the behavior ... when the given bytes are not valid in the default charset is unspecified". In the test case provided, the first two bytes of the serialization stream, 0xac and 0xed (see java.io.ObjectStreamConstants.STREAM_MAGIC), both get mapped to the character '?' since they are not valid in the default charset (ISO646-US in the JDK I'm running). The two '?' characters are then mapped back to the byte sequence 0x3f 0x3f in the reconstructed data stream, which do not constitute a valid header. The solution, from the perspective of the test case, is to use ByteArrayOutputStream.toByteArray() instead of toString(), which will yield the raw byte sequence; this can then be fed directly to the ByteArrayInputStream(byte[]) constructor.
一个测试:
public static void main(String[] args) throws Exception { short t = (short) 0xaced;//copy from java.io.ObjectStreamConstants.STREAM_MAGIC System.out.println(0xaced); //44269写入到byte[] = -84,-19,0,5, ByteArrayOutputStream buffer = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(buffer); out.writeShort(t); byte[] data = buffer.toByteArray(); for(byte b:data) { System.out.print(b+","); } System.out.println(); String text= new String(data); System.out.println(text); // 输出 �� data = text.getBytes(); for(byte b:data) { System.out.print(b+","); // 输出 -17,-65,-67,-17,-65,-67,0,5, } }
相关推荐
【Android多点触控技术实战】在Android应用开发中,多点触控技术是一项重要的交互设计,它使得用户可以通过两个或更多的手指同时操作屏幕,从而实现更丰富的交互体验。在这个场景下,我们专注于如何实现图片的自由...
项目中碰到的,记录一下解决方案
3. 异常处理:文件中提及了“Exception”、“InterruptedException”、“StreamCorruptedException”,这些都是Java异常处理的一部分。在Java中,异常处理通过“try”、“catch”、“finally”和“throw”、“throws...
8. **反序列化异常处理**:在进行反串行化时,务必准备好处理可能的异常,例如`InvalidClassException`、`StreamCorruptedException`等。 9. **数据格式兼容性**:如果你的应用需要跨平台或跨语言,选择一种通用的...
当使用`ObjectOutputStream`向文件中多次追加对象时,可能导致`StreamCorruptedException`异常。这是因为序列化过程中会为每个对象写入一个标识头,而反序列化时只能识别一个标识头。解决方法是自定义`...