`

解决序列化中的问题 java.io.StreamCorruptedException: invalid stream header: EFBFBDEF

阅读更多

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.

 

3
6
分享到:
评论
5 楼 u010311110 2016-09-13  
4 楼 zczjdyj123 2015-05-11  
3 楼 laogao3232 2012-10-31  
有什么意义?
2 楼 sziitjiang 2012-08-07  
1 楼 shijianwen520 2011-08-19  

相关推荐

    Android多点触控技术实战 针对图片自由缩放和移动

    【Android多点触控技术实战】在Android应用开发中,多点触控技术是一项重要的交互设计,它使得用户可以通过两个或更多的手指同时操作屏幕,从而实现更丰富的交互体验。在这个场景下,我们专注于如何实现图片的自由...

    java.io.StreamCorruptedException(解决方案).md

    项目中碰到的,记录一下解决方案

    java概念题汇总.pdf

    “ObjectOutputStream”和“ObjectInputStream”用于Java对象的序列化和反序列化,这在需要网络传输或存储对象状态时十分有用。 7. 其它Java知识点:文件还显示了关于“abstract”类和“interface”的讨论,以及...

    串行化保存和读取数据示例.zip

    在编程领域,串行化(Serialization)是一种将对象的状态转换为可以存储或传输的数据格式的过程。这个过程使得数据能够在不同的...通过上述知识点的学习和实践,你将能够更好地利用Java的串行化特性来解决实际问题。

    中科软,文思 面试题

    这是因为序列化过程中会为每个对象写入一个标识头,而反序列化时只能识别一个标识头。解决方法是自定义`ObjectOutputStream`子类,并覆盖`writeStreamHeader()`方法以控制标识头的写入。 #### Java代码示例分析 **...

Global site tag (gtag.js) - Google Analytics