使用Java压缩ZIP中的大文件

时间:2009-11-20 14:28:16

标签: java zip large-files

我需要通过Java类ZipOutputStream压缩一个Big文件(~450 MB)。这个大维度导致我的JVM堆空间出现“OutOfMemory”错误。发生这种情况是因为“zos.write(...)”方法将所有文件内容存储在压缩内部字节数组中以进行压缩。

            origin = new BufferedInputStream(fi, BUFFER);
        ZipEntry entry = new ZipEntry(filePath);
        zos.putNextEntry(entry);

        int count;
        while ((count = origin.read(data, 0, BUFFER)) != -1)
        {
            zos.write(data, 0, count);
        }
        origin.close();

自然的解决方案是扩大JVM的堆内存空间,但我想知道是否有一种方法以流方式写入这些数据。我不需要高压缩率,所以我也可以改变算法。

有人对此有所了解吗?

4 个答案:

答案 0 :(得分:10)

根据您对Sam的回复的评论,您显然创建了一个ZipOutputStream,它包装了一个ByteArrayOutputStream。 ByteArrayOutputStream当然将压缩结果缓存在内存中。如果要将其写入磁盘,则必须将ZipOutputStream包装在FileOutputStream周围。

答案 1 :(得分:3)

我有一个名为TrueZip的图书馆,我过去曾用它做过这样的事情。

我不能保证它在缓冲前面做得更好。我知道它使用自己的编码做了很多事情,而不是依赖于JDK的Zip API。

在我看来,值得一试。

答案 2 :(得分:1)

ZipOutputStream是基于流的,它不会保留在内存中。你的BUFFER可能太大了。

答案 3 :(得分:0)

我想知道是不是因为你将内容存储在ZipEntry中,也许它基本上会在写出ZipEntry之前加载它的所有内容。你必须使用Zip吗?如果只需要压缩一个数据流,则可以查看GZIPOutputStream。我相信它不会有同样的问题。

希望这有帮助。