java.io.StreamCorruptedException: invalid stream header: EFBFBDEF 问题解决
错误方式
@Test
public void testDeserializeTest() 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();
assertEquals(obj.getClass().getName(), "java.math.BigInteger");
assertEquals(((BigInteger) obj).intValue(), 0);
}
@Test
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);
}
原因是由于:
将字 ByteArrayOutputStream对象调用为toString转为为字符串时,会将 ObjectOutputStream对象放置在对象流头部的前两个字节(0xac)(0xed)序列化为两个“?”
当这个字符串使用getByte()时会将两个“?”变为(0x3f )(0x3f) 。然而这两个字符并不构成有效的对象流头。所以转化对象时候会失败。
测试代码 单元测试无法输出结果这里用main测试
public static void main(String[] args) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
String s = "111";
oos.writeObject(s);
String str = baos.toString();
byte[] baStr = baos.toByteArray();
byte[] gbStr = str.getBytes();
byte[] testStr = baStr;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < testStr.length; i++) {
sb.append(Integer.toBinaryString(testStr[i]) + " ");
}
System.out.println(sb.toString());
}
1.如果将6行的str直接打印在页面上 则显示如下结果
2.将第9行赋予baStr 则得到的二进制首两位值为
11111111111111111111111110101100(0xac) 11111111111111111111111111101101(0xed)
3.将第9行赋予gbStr 则得到的二进制首两位值为
11111111111111111111111111101111(0xef) 11111111111111111111111110111111(0xbf)
(由于字符集和英文原作者不一样所以解析出来的结果也不一样)
发现字符被改变了以至于ObjectOutputStream无法识别该字符数组所以抛出了java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
所以笔者建议:
1.使用 toByteArray()代替toString() ,使用 ByteArrayInputStream(byte [])构造函数。
2.使用base64转换为字符串
注:LZ出现这个问题是因为在maven打包项目的时候重新编译了项目中的二进制文件从而破坏了二进制文件的完整性。所以该文件无法反序列化。
附:maven打包跳过二进制文件
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<!-- 防止二进制文件被编译 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>dat</nonFilteredFileExtension>
<nonFilteredFileExtension>swf</nonFilteredFileExtension>
<nonFilteredFileExtension>xml</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
英文原文:
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.
原文地址 http://blog.sina.com.cn/s/blog_61f4999d0100yi89.html
java.io.StreamCorruptedException: invalid stream header: EFBFBDEF 问题解决的更多相关文章
- java.io.StreamCorruptedException: invalid stream header: 00000000
Caused by: java.io.StreamCorruptedException: invalid stream header: 00000000 at java.io.ObjectInputS ...
- java——解决"java.io.StreamCorruptedException: invalid stream header: xxx"
这个错误是由序列化引起的,可能的原因以及解决方法: 1.kryo对于集合(比如 Map)的反序列化会失效,报这个错误,解决办法比较暴力,不用kryo了,直接用java原生方法. 2.使用Java原生方 ...
- invalid stream header: EFBFBDEF 问题解决
我们项目使用report 报表功能,然后在加载xxxx.jasper文件时候报的invalid stream header: EFBFBDEF 的错误 public JasperPrint fill( ...
- ObjectInputStream java.io.StreamCorruptedException: invalid type code: AC问题解决
感谢原文作者:攻城狮_无名 原文链接:https://blog.csdn.net/mingyang_2016/article/details/75208117 问题描述: 每次向一个文件中序列化对象时 ...
- java.io.StreamCorruptedException: invalid type code: AC错误的解决方法
问题描述: 在向一个文件写入可序列化对象时,每次只想向文件的末尾添加一个可序列化的对象,于是使用了FileOutputStream(文件名,true)间接的构建了ObjectOutputStream流 ...
- 对象反序列化时,抛出java.io.StreamCorruptedException: invalid type code: AC异常
问题描述:在使用java.io.ObjectInputStream类的readObject()方法去读取包含有序列化了多个(两个及两个以上)类的文件时,当读取到第二个类时,会抛出题目中提到的异常. 原 ...
- invalid stream header: 31323334
记录一下,都配置好了之后,用java客户端设置key-value,在服务器get没有问题,然后再服务器端设置一个key-value,java客户端获取出错 转载一下网上同样问题的描述,以及解决方案 严 ...
- java.io.IOException: invalid header field
通过本文, 我们明白了什么是 jar的清单文件 MANIFEST.MF, 简单示例: E:\ws\Test\WEB-INF\classes>jar cvfm testCL.jar ListTes ...
- java打包遇到问题java.io.IOException: invalid header field
问题:java打包时报以下错误 $ jar -cvmf main.txt test.jar Shufile1.class java.io.IOException: invalid header fie ...
随机推荐
- Delphi : 制作程序启动欢迎界面
制作欢迎界面的代码,大家参考 登陆窗体命名為:loginform.找到工程文件(Project -> View Source),找到如下代碼部分:begin Application.Init ...
- 实体框架自定义代码优先约定(EF6以后)
仅限EF6仅向前 - 此页面中讨论的功能,API等在实体框架6中引入.如果您使用的是早期版本,则部分或全部信息不适用. 使用Code First时,您的模型是使用一组约定从您的类计算的.默认的Code ...
- iOS RSA的加密和签名
1.RSA加密使用服务端给的公钥.pem,RSA签名使用客户端的私钥.pem. 参考文章:http://www.jianshu.com/p/4580bee4f62f 把文件夹导入项目中,然后配置这两个 ...
- MT【194】又见和式变换
(2007浙江省赛B卷最后一题)设$\sum\limits_{i=1}^{n}{x_i}=1,x_i>0,$求证:$n\sum\limits_{i=1}^n{x_i^2}-\sum\limits ...
- 【题解】 [HNOI2009] 最小圈 (01分数规划,二分答案,负环)
题目背景 如果你能提供题面或者题意简述,请直接在讨论区发帖,感谢你的贡献. 题目描述 对于一张有向图,要你求图中最小圈的平均值最小是多少,即若一个圈经过k个节点,那么一个圈的平均值为圈上k条边权的和除 ...
- stm32的双向io口
# stm的io设置为双向问题,将io端口模式配置为 open-drain mode > 在io端口配置为输出模式时,输入通道上的施密特触发器一直是打开的,所以读取IDR是能检测到端口电平的 & ...
- 解题:NOI 2014 随机数生成器
题面 为什么NOI2014有模拟题=.=??? 按题意把序列生成出来之后,对每一行维护一个能取到的最左侧和能取到的最右侧.从小到大$O(n^2)$枚举数字看看能否填入,能填入则暴力$O(n)$更新信息 ...
- c读入实型
读入: 如果读入的数为整型,然后转为实型,则%lf 否则%f也可以 读出: %f,这样在codeblocks才能看到正确的结果
- LeetCode 7最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- Redis的持久化数据
Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot).AOF:持久化记录服务器执行的 ...