java – 通过GZIP流读取和写入对象?

我是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
上一篇:java-将一组具有相似性的字符串映射到较短的字符串


下一篇:javascript-使用快速压缩来压缩来自其余node.js的json数据