我有一些非常标准的代码,它从流中获取序列化对象,基本上看起来像这样:
Object getObjectFromStream(InputStream is) { ObjectInputStream ois = new ObjectInputStream(is); return ois.readObject(); }
然后我在我的资源文件夹中有一个文件,所以在我的开发机器上,我可以将它作为文件引用,或者作为JarResource引用:
InputStream is = new FileInputStream("/home/.../src/main/resources/serializedObjects/testObject"); InputStream is = this.getClass().getResourceAsStream("/serializedObjects/testObject");
在我的脑海中,两者都应该做同样的事情。但是,它会解析为有效(非空)流,但FileInputStream正确地从我的getObjectFromStream(InputStream)方法返回一个Object,而getResourceAsStream版本抛出此异常:
java.io.StreamCorruptedException: invalid stream header: EFBFBDEF at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:800) at java.io.ObjectInputStream.(ObjectInputStream.java:297)
大多数情况下,我想知道如何解决这个问题,但我也很欣赏对两个InputStream之间差异的理解...
答案 0 :(得分:18)
EFBFBD
是Unicode替换字符U + FFFD的UTF-8表示。所以,看起来文件是通过一些编码转换过程传递的。
Maven可能是一个嫌疑人,尤其是它的资源过滤功能。
答案 1 :(得分:7)
在你的情况下,Maven正在弄乱你的文件,但是由于不同的原因我发现了同样的事情,所以我在这里记录它,因为这是Google上唯一有用的搜索结果。
我将序列化对象保存为单元测试的数据集,并将它们存储在版本控制中。这是否是一个好主意是辩论,但另一次。
文件以:
开头AC ED 00 05 ...
将它们存储在Git中之后,它们变为:
EF BF BD EF BF BD 00 05 ...
这会导致错误:
java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:782)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
Git不仅会更改这些开放字节,还会更改整个文件中的许多字节。它试图在Windows和Unix风格的行结尾之间进行转换。用于识别文件是否包含文本的启发式算法失败。
解决方案是添加一个.gitattributes
文件,指定要从此处理中排除的一些文件:
*.bytes -crlf
我还确保我的.git/config
文件具有以下内容:
[core]
autocrlf = false
通过这些更改,我删除了索引并强制重置:
rm .git/index
git reset # force rescan of the index
git status # any files listed here will experience changes
git add -u
git commit -m "Line ending normalisation changes."
希望能帮助别人。我不是Git的大师,所以可能不需要其中一些步骤,但它们对我有用。
答案 2 :(得分:6)
这个对我有用。
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
<nonFilteredFileExtension>jrxml</nonFilteredFileExtension>
<nonFilteredFileExtension>jasper</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
答案 3 :(得分:1)
一个问题是maven尝试过滤资源文件夹中的所有内容。创建一个单独的文件夹,然后指示maven不要过滤它。
<resources>
<resource>
<directory>${basedir}/bin</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
答案 4 :(得分:0)
根本没有区别 - 你为getResourceAsStream()使用的路径必须找到其他文件。搜索存储为serializedObjects / testObject的其他文件,看看是否找不到它。请记住,FileInputStream将相对于当前目录进行查找,而getResourceAsStream()则相对于类路径。