9

我需要通过 Java 类 ZipOutputStream 压缩一个大文件(~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

4 回答 4

11

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

于 2009-11-20T14:59:35.543 回答
3

有一个名为TrueZip的库,我过去曾成功地使用它来做这种事情。

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

所以在我看来,值得一试。

于 2009-11-20T14:35:37.597 回答
1

ZipOutputStream 是基于流的,它不占用内存。您的 BUFFER 可能太大。

于 2009-11-20T14:35:46.823 回答
0

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

希望这可以帮助。

于 2009-11-20T14:42:58.877 回答