java IO 篇之ObjectOutputStream、ObjectInputStream


public class TransObjectJava implements TransObject{

@Override
public Person decoder(String objstr) {
ObjectInputStream ois = null;
try {
ByteArrayInputStream bai = new ByteArrayInputStream(objstr.getBytes());
ois = new ObjectInputStream(bai);
Person obj = (Person)ois.readObject();
return obj;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}finally{
try {
ois.close();
ois = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

@Override
public String encoder(Person obj) {
ObjectOutputStream oos = null;
try{
ByteArrayOutputStream bao = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bao);
oos.writeObject(obj);
return bao.toString();
}catch(Exception e){
e.printStackTrace();
return null;
}finally{
try {
oos.close();
oos = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


}
}



对象序列化、反序列化过程将对象以string形式输出,以byte[] 方式反序列化成对象
报异常 java.io.StreamCorruptedException: invalid stream header: EFBFBDEF,原因如下:

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.


因为序列化时,加入对象header的字节 final static short STREAM_MAGIC = (short)0xaced; 在默认的字符集中为无效字节,标记为?,反序列化时就无法正常还原对象header数据,因此反序列化失败

解决方法如下:
1、序列化输出字节数组 byteArrayOutputStream.toByteArray();
反序列化用字节数组还原对象
2、序列化输出字符串,使用ISO-8859-1编码 byteArrayOutputStream.toSting("ISO-8859-1");反序列化时使用ISO-8859-1编码还原对象 ByteArrayInputStream bai = new ByteArrayInputStream(objstr.getBytes("ISO-8859-1"));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值