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 ...
随机推荐
- php 的优缺点
1.优点:开源 免费性 快捷性 [程序开发快,运行快,技术本身学习快] 插件丰富,网上的解决方案有很多,而且还有庞大的开源社区可以提供帮助. 跨平台性强 效率高 图像处理 面向对象 [在php4 ...
- JVM学习笔记(四):类加载机制
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 一.类加载的时机1. 类从被加载到虚拟机内存 ...
- BZOJ5461 PKUWC2018Minimax(概率期望+线段树合并+动态规划)
离散化后,容易想到设f[i][j]为i节点权值为j的概率,不妨设j权值在左子树,则有f[i][j]=f[lson][j](pi·f[rson][1~j]+(1-pi)·f[rson][j~m]). 考 ...
- 棋盘游戏 HDU - 1281 (删点 二分匹配)
小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的“车”,并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才可以放,小希还是很轻松的解决 ...
- MT【75】考察高斯函数的一道高考压轴题
解答:答案1,3,4. 这里关于高斯函数$[x]$的一个不等式是需要知道的$x-1<[x]\le x$,具体的:
- BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数
BZOJ 2440 [中山市选2011]完全平方数 | 莫比乌斯函数 题面 找出第k个不是平方数的倍数的数(1不是平方数, \(k \le 10^9\)). 题解 首先二分答案,问题就转化成了求\([ ...
- jupyter notebook添加Anaconda虚拟环境的python kernel
之前在自己博客上写了一个如何通过自建配置文件,让jupyter notebook可以调用conda虚拟环境的python解释器. 今天介绍一种更加简单的方式,无需手动配置文件,利用ipykernel可 ...
- 使用IntelliJ IDEA工具创建SSM(Spring+MyBatis)项目
1. 安装和使用IntelliJ IDEA 参考:IntelliJ IDEA 的安装和使用教程 2. 创建Web项目 参考:IntelliJ IDEA 创建Java Web项目 3. Spring整合 ...
- 解题:HNOI 2013 Cards
题面 除了不洗牌以外,每种洗牌方式的每个循环里的颜色必须一样,然后大力背包一下就好了.最后记得把不洗牌的方案也算进去 #include<cstdio> #include<cstrin ...
- bzoj 4464 : [Jsoi2013]旅行时的困惑
网络流建图. 从S向每个点连边,从每个点向T连边. 每条树边反向连一条下界为1,上界inf的边. 跑最小流. 注意加当前弧优化. #include<cstdio> #include< ...