我是Java新手.我想学习使用GZIPstreams.我已经尝试过这个:
ArrayList<SubImage>myObject = new ArrayList<SubImage>(); // SubImage is a Serializable class
ObjectOutputStream compressedOutput = new ObjectOutputStream(
new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(
new File("....")))));
compressedOutput.writeObject(myObject);
和
ObjectInputStream compressedInput = new ObjectInputStream(
new BufferedInputStream(new GZIPInputStream(new FileInputStream(
new File("....")))));
myObject=(ArrayList<SubImage>)compressedInput.readObject();
当程序将myObject写入文件时不会抛出任何异常,但是当它到达该行时
myObject=(ArrayList<SubImage>)compressedInput.readObject();
它抛出此异常:
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
我怎么解决这个问题?
解决方法:
您必须刷新并关闭输出流.另外,至少,BufferedOutputStream不会将所有内容都写入文件(它可以用大量的chuck来避免性能下降).
如果你调用compressedOutput.flush()和compressedOutput.close()就足够了.
您可以尝试编写一个简单的字符串对象并检查文件是否写得很好.
怎么样?如果您编写xxx.txt.gz文件,可以使用首选的zip应用程序打开它,然后查看xxx.txt.如果应用程序抱怨,则内容未完整写入.
评论的扩展答案:压缩更多数据
改变序列化
如果SubImage对象是您自己的对象,则可以更改它的标准序列化.检查java.io.Serializable javadoc以了解如何操作.这很简单.
写出你需要的东西
序列化的缺点是需要在您编写的每个实例之前编写“它是一个SubImage”.如果你事先知道会有什么,那就没有必要了.所以你可以尝试更多地手动序列化它.
要编写列表,而不是编写对象直接写入符合列表的值.您将只需要一个DataOutputStream(但ObjectOutputStream是一个DOS,因此您无论如何都可以使用它).
dos.writeInt(yourList.size()); // tell how many items
for (SubImage si: yourList) {
// write every field, in order (this should be a method called writeSubImage :)
dos.writeInt(...);
dos.writeInt(...);
...
}
// to read the thing just:
int size = dis.readInt();
for (int i=0; i<size; i++) {
// read every field, in the same order (this should be a method called readSubImage :)
dis.readInt(...);
dis.readInt(...);
...
// create the subimage
// add it to the list you are recreating
}
此方法更具手动性,但如果:
>你知道会写什么
>对于许多类型,您不需要这种序列化
与Serializable相比,它的价格非常实惠且压缩性更强.
请记住,有序列化对象或创建字符串消息的替代框架(XStream for xml,Google Protocol Buffers for binary messages等).该框架可以直接用于二进制或编写可以随后编写的字符串.
如果你的应用程序需要更多,或只是好奇,也许你应该看看它们.
替代序列化框架
刚看了SO,发现了几个解决这个问题的问题(和答案):
https://*.com/search?q=alternative+serialization+frameworks+java
我发现XStream非常简单易用. JSON是一种非常易读和简单的格式(和Javascript兼容,可能是一个加号:).
我应该去:
Object -> JSON -> OutputStreamWriter(UTF-8) -> GZippedOutputStream -> FileOutputStream