问题
This is my code:
WritableByteChannel channel = null;
GZIPOutputStream out = null;
try {
channel = Channels.newChannel(new FileOutputStream("C:\\temp\\111.zip"));
out = new GZIPOutputStream(Channels.newOutputStream(channel));
for (long i = 0; i < 10000000000; i++) {
out.write(("string" + i + "\n").getBytes());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (channel != null) {
channel.close();
}
} catch (Exception e) {
}
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
}
} }
I get zip but it's contents is damaged.
回答1:
Why are you saving it as zip if you're using a gzip stream? Use .gz as the extension.
Edit
Assuming that it's not the .zip extension at fault here (it's still bad though):
- You should probably consider calling
out.finish()before closing it. - I'm pretty sure you don't need all the channel stuff. You can simply pass the FileOutputStream to GZIPOutputStream
回答2:
I would do:
GZIPOutputStream gzipOS = new GZIPOutputStream(new FileOutputStream("C:\\temp\\111.gz"));
WritableByteChannel out = Channels.newChannel(gzipOS);
And simply use out.write() to write using NIO. Don't forget to close resources later.
回答3:
When you call out.close() it will close the underlying stream/channel as well.
If you close the underlying channel first any buffered data or footer cannot be written.
The GZIP format contains a CRC32 which must be at the end, cannot be written until you clsoe the stream and I expect this is missing so the file contents cannot be validated. The simplest solution is to not close the underlying channel yourself.
BTW: As a rule it is usually best to close resources in the reverse order they were created. ;)
来源:https://stackoverflow.com/questions/9394098/writing-gzip-file-with-nio