2015-10-01 83 views
3

我想創建一個填充PDF-As的ZipOutputStream。我正在使用iText(版本5.5.7)。對於超過1000個pdf條目,我在doc.close()上得到一個OutOfMemory-exception,並且找不到該泄漏。iText - 創建超過1000個PDF的OutOfMemory

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(baos)); 
zos.setEncoding("Cp850"); 
for (MyObject o : objects) { 
try { 
    String pdfFilename = o.getName() + ".pdf"; 
    zos.putNextEntry(new ZipEntry(pdfFilename)); 
    pdfBuilder.buildPdfADocument(zos); 
    zos.closeEntry(); 
} ... 

PdfBuilder

public void buildPdfADocument(org.apache.tools.zip.ZipOutputStream zos){ 
    Document doc = new Document(PageSize.A4); 
    PdfAWriter writer = PdfAWriter.getInstance(doc, zos, PdfAConformanceLevel.PDF_A_1B); 
    writer.setCloseStream(false); // to not close my zos 
    writer.setViewerPreferences(PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage); 
    writer.createXmpMetadata(); 
    doc.open(); 
    // adding Element's to doc 
    // with flushContent() on PdfPTables 
    InputStream sRGBprofile = servletContext.getResourceAsStream("/WEB-INF/conf/AdobeRGB1998.icc"); 
    ICC_Profile icc = ICC_Profile.getInstance(sRGBprofile); 
    writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc); 
    //try to close/flush everything possible 
    doc.close(); 
    writer.setXmpMetadata(null); 
    writer.flush(); 
    writer.close(); 
    if(sRGBprofile != null){ 
    sRGBprofile.close(); 
    } 
} 

任何建議,我該如何解決?我忘記了什麼嗎? 我已經嘗試使用java ZipOutputStream,但它有任何區別。


Thx for ur answers!我理解ByteOutputStream的問題,但我不確定在我的情況下最好的方法是什麼。這是一個Web應用程序,我需要以某種方式將zip壓縮到數據庫blob中。

我現在正在做的是直接用iText創建PDF到ZipOutputStream中,並將相應的ByteArrayOutputSteam的字節數組保存爲blob。我看到的選項是:

將我的數據拆分爲500個對象包,將前500個PDF保存到數據庫中,然後打開zip並添加下一個500等等......但我認爲這會創建我與我現在一樣的情況,即在記憶中打開太大的流。

儘量節省服務器(不知道是否有足夠的空間),創建臨時zip文件,然後提交字節的BLOB的PDF文件...

任何建議/想法?

+1

請勿使用ByteArrayOutputStream,因爲它會在內存中構建整個zip文件。嘗試使用FileOutputStream來代替。 – Palamino

+0

如果ZIP太大,它已經使得服務器端vm(通常會有相當多的內存)出現內存不足,這肯定是使用硬盤空間而不是流式傳輸數據庫(如果有問題的數據庫提供這樣一個真正的流媒體界面,那就是)。話雖如此,將這麼大的ZIP存儲在單個BLOB中真的有意義嗎?每個PDF的一個BLOB設計不會更靈活嗎? – mkl

回答

0

您需要使用其他方法來處理這個數量的參數(超過1000個文件)。

您正在載入您的示例中的所有PDF文件,您需要在文檔塊中執行此操作以最大限度地減少此「內存負載」的影響。

另一種方法是在文件系統上序列化您的PDF,然後創建您的zip文件。

4

這是因爲您的ZipOutputStream由ByteArrayOutputStream支持,所以即使關閉條目也會將完整的ZIP內容保留在內存中。