我想創建一個填充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文件...
任何建議/想法?
請勿使用ByteArrayOutputStream,因爲它會在內存中構建整個zip文件。嘗試使用FileOutputStream來代替。 – Palamino
如果ZIP太大,它已經使得服務器端vm(通常會有相當多的內存)出現內存不足,這肯定是使用硬盤空間而不是流式傳輸數據庫(如果有問題的數據庫提供這樣一個真正的流媒體界面,那就是)。話雖如此,將這麼大的ZIP存儲在單個BLOB中真的有意義嗎?每個PDF的一個BLOB設計不會更靈活嗎? – mkl