2015-12-07 27 views
-1

我在做跟隨的東西與Java遇到了一個問題:文件在列表<File>被「打開」,並得到了內存

  1. 創建.xls文件,並寫在服務器中有一些內容。
  2. 將此文件存儲到列表中。
  3. 重複第1步和第2步數千次,並獲得一個包含數千個.xls文件的列表。
  4. 將文件導出到.zip文件中。

我的問題是似乎創建的文件都是「打開」,它將是內存不足。實際上每個文件只有大約37kb,文件數量只有大約2000個。我認爲它不是太多,但每次都失敗。所以任何人都對這個問題有一些想法?非常感謝!

+0

您應該提供您獲得的實際錯誤以及代表性的代碼示例。 – FatalError

+0

37k * 2000 = 74兆字節。這不是「很多」,但它一次只能存儲大量內存。你的應用需要內存本身才能運行。這個應用程序的內存參數是如何配置的?你有沒有給應用程序至少幾GB的運行? – markspace

+0

您沒有發佈實際的錯誤消息,我懷疑你沒有文件句柄,而不是內存。 – chrylis

回答

2

問題是你正在以錯誤的方式處理這個過程。 ZIP文件不是通過將每個文件讀入內存,壓縮它,然後寫入輸出來構建的。相反,它一次寫入一個文件,只有目錄列表存儲在內存中。在僞代碼,這意味着你這樣做:

Create Zip Memory Directory 
Open Zip File Handle 
For Each File In Directory 
    Open File In Read Mode 
    Compress File 
    Write Headers and File To Zip File 
    Store Info About File in Zip Memory Directory 
    Close File 
End For 
Write Zip Memory Directory to Zip File 
Close Zip File Handle 

這意味着僅在需要時對單個文件進行壓縮需要儘可能多的內存,而你只需要兩個文件在任何給定的時間打開。這部分是因爲大多數系統都具有有限的空間(「句柄」)來跟蹤打開的文件,因此根據語言/操作系統/任何情況,您可能實際上正在耗盡您的平臺對每個線程/進程/整個文件句柄的限制系統。同樣,解壓縮通常也一次實現一個文件。在Java中,您可能實際上使用Zip實用程序類,讀取每個文件,將其壓縮到內存中的某個位置,然後關閉該文件並循環其餘文件;在整個過程結束時,將Zip文件保存到磁盤。

請參閱ZipOutputStream您可以使用的一個這樣的類。實際上,它通過接受OutputStream(通過以寫入模式打開文件創建),然後在循環中調用putNextEntry,write,closeEntry,最後調用close()將文件刷新到磁盤來工作。

相關問題