2012-06-19 116 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