2012-06-19 81 views
2

我已经在android中制作了一个应用程序,它允许用户压缩和解压缩文件,并使用包java.util.zip。一切正常。速度,文件与目录一起被完全压缩和解压缩。唯一的问题是应用程序无法压缩/解压大文件(大于1GB)。Java压缩/解压缩大文件(> 1GB)

我相信问题是我的buffer的大小。我见过的其他代码,其缓冲区的值是1024或2048或8192,但是我的缓冲区的值是根据所选文件的大小(为了使其灵活)。但是一旦用户选择了一个大文件(大小大于8位数字),那就是错误出现了。我在网上搜索,也在这个网站,但我找不到答案。我的问题是与此类似:

To Compress a big file in a ZIP with Java

谢谢你的未来帮助! :)

编辑:

感谢您的意见和解答。它确实帮了很大忙。我认为BUFFER在压缩/解压缩在java意味着文件的大小,所以在我的程序中,我使缓冲区大小灵活(缓冲区大小=文件大小)。请有人解释缓冲区是如何工作的,所以我可以理解为什么BUFFER具有固定值。同样对于我来说,为什么其他人会告诉我们,如果缓冲区大小为8k或更好,它会更好。非常感谢! :)

+2

请发表您的代码 - 尤其是当你选择的缓冲区大小的部分。我怀疑你的缓冲区太大了。 – Polynomial

+2

根据文件大小,不需要调整缓冲区大小。如果有的话,它需要调整以匹配它下面的I/O层。这是棘手的,可能不便携。只需要一个固定的缓冲区大小。 – Thilo

+0

多项式,你的权利是我的情况。由于Thilo评论过的内容,我意识到我误解了'buffer'的功能。 +1给你们两个。所以这意味着一个缓冲区的固定值可以压缩/解压任何大小的文件?那么不同缓冲区大小的目的是什么? 1024,2048,8192等等? – John

回答

4

如果将缓冲区大小设置为文件大小,那么意味着只要文件大小太大而无法使用内存,就会出现OutOfMemoryError。

使用正常的缓冲区大小,让它做到这一点 - 以流式方式缓冲数据,一次一个块,而不是一次一个。

为了说明,参见例如的BufferedOutputStream文档:

该类实现缓冲的输出流。通过设置这样一个输出流,应用程序可以将字节写入底层输出流 流,而不必对每个字节写入底层系统调用 。

因此,使用缓冲区比非缓冲区写入效率更高。

而且从write方法:

一般来说,此方法存储从给定的阵列到此 流的缓冲区字节,冲洗缓冲液根据需要基础输出流 。但是,如果所请求的长度至少与此流的缓冲区一样大,则此方法将刷新缓冲区,并将字节直接写入基础输出流。

每次写入都会导致内存缓冲区填满,直到缓冲区满。当缓冲区满时,它将被刷新并清除。如果使用非常大的缓冲区,则会在刷新之前将大量数据存储在内存中。如果你的缓冲区与输入文件大小相同,那么你就说你需要在整个内容读入内存之前先将其清空。使用默认的缓冲区大小通常很好。将会有更多的物理写入(刷新);你避免了爆炸的记忆。

通过允许您指定特定的缓冲区大小,API可让您选择内存消耗和I/O之间的适当平衡以适合您的应用程序。如果您调整应用程序的性能,您可能会调整缓冲区大小。但是在很多情况下,默认大小都是合理的。

+1

良好的缓冲区大小将约为8K –

+0

是的,这是我的情况。 OutOfMemoryError异常。你还会向我解释缓冲区的工作原理吗?因为我认为缓冲区大小必须等于文件的大小。非常感谢! – John

+0

康斯坦丁,感谢您的建议!但是,你能向我解释为什么让我有更好的理解。谢谢! :) – John

1

这听起来像这将有助于简单地将缓冲区像一个最大尺寸的东西:

//After calculating the buffer size bufSize: 
bufSize = Math.min(bufSize, MAXSIZE); 
+0

为什么使缓冲区更大? – Thilo

+0

@Thilo不知道,8K以上的缓冲区大小通常提供很少的好处。我只是假定约翰想要使用可变缓冲区,因为这正是他正在做的。 – Jave