我是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
我该如何解决这个问题?
答案 0 :(得分:6)
您必须刷新并关闭输出流。至少,BufferedOutputStream
不会将所有内容都写入文件(为了避免影响性能,它会在大文件中写入)。
如果您拨打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版本更加压缩。
请记住,有序列化对象或创建字符串消息的替代框架(xSt的XStream,二进制消息的Google Protocol Buffers等)。该框架可以直接用于二进制或编写可以随后编写的字符串。
如果你的应用需要更多,或只是好奇,也许你应该看看它们。
替代序列化框架
刚看了SO,发现了几个问题(和答案)解决了这个问题:
https://stackoverflow.com/search?q=alternative+serialization+frameworks+java
我发现XStream非常简单易用。 JSON是一种非常易读且易于使用的格式(与Javascript兼容,这可能是一个优点:)。
我应该去:
Object -> JSON -> OutputStreamWriter(UTF-8) -> GZippedOutputStream -> FileOutputStream