Java pdf合并期间的OutOfMemoryError
下面的代码合并pdf文件并返回组合的pdf数据。当代码运行时,我尝试将100个文件与每个大约500kb的文件组合在一起,但在行文档.close()中出现了outofmemory错误;。此代码在web环境中运行,内存是否可用于web服务器?问题出在哪里?我在一篇文章中读到使用freeReader方法,但我不知道如何在我的场景中使用它Java pdf合并期间的OutOfMemoryError,java,pdf,merge,itext,Java,Pdf,Merge,Itext,下面的代码合并pdf文件并返回组合的pdf数据。当代码运行时,我尝试将100个文件与每个大约500kb的文件组合在一起,但在行文档.close()中出现了outofmemory错误;。此代码在web环境中运行,内存是否可用于web服务器?问题出在哪里?我在一篇文章中读到使用freeReader方法,但我不知道如何在我的场景中使用它 protected ByteArrayOutputStream joinPDFs(List<InputStream> pdfStreams,
protected ByteArrayOutputStream joinPDFs(List<InputStream> pdfStreams,
boolean paginate) {
Document document = new Document();
ByteArrayOutputStream mergedPdfStream = new ByteArrayOutputStream();
try {
//List<InputStream> pdfs = pdfStreams;
List<PdfReader> readers = new ArrayList<PdfReader>();
int totalPages = 0;
//Iterator<InputStream> iteratorPDFs = pdfs.iterator();
Iterator<InputStream> iteratorPDFs = pdfStreams.iterator();
// Create Readers for the pdfs.
while (iteratorPDFs.hasNext()) {
InputStream pdf = iteratorPDFs.next();
if (pdf == null)
continue;
PdfReader pdfReader = new PdfReader(pdf);
readers.add(pdfReader);
totalPages += pdfReader.getNumberOfPages();
}
//clear this
pdfStreams = null;
//WeakReference ref = new WeakReference(pdfs);
//ref.clear();
// Create a writer for the outputstream
PdfWriter writer = PdfWriter.getInstance(document, mergedPdfStream);
writer.setFullCompression();
document.open();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
// data
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
// Loop through the PDF files and add to the output.
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
// Create a new page in the target for each source page.
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
pageOfCurrentReaderPDF++;
document.setPageSize(pdfReader
.getPageSizeWithRotation(pageOfCurrentReaderPDF));
document.newPage();
// pageOfCurrentReaderPDF++;
currentPageNumber++;
page = writer.getImportedPage(pdfReader,
pageOfCurrentReaderPDF);
cb.addTemplate(page, 0, 0);
// Code for pagination.
if (paginate) {
cb.beginText();
cb.setFontAndSize(bf, 9);
cb.showTextAligned(PdfContentByte.ALIGN_CENTER, ""
+ currentPageNumber + " of " + totalPages, 520,
5, 0);
cb.endText();
}
}
pageOfCurrentReaderPDF = 0;
System.out.println("now the size is: "+pdfReader.getFileLength());
}
mergedPdfStream.flush();
document.close();
mergedPdfStream.close();
return mergedPdfStream;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document.isOpen())
document.close();
try {
if (mergedPdfStream != null)
mergedPdfStream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return mergedPdfStream;
}
受TearrayOutstream JoinPDF保护(列出PDF流,
布尔分页){
文档=新文档();
ByteArrayOutputStream mergedPdfStream=新建ByteArrayOutputStream();
试一试{
//列出PDF=PDF流;
列表读取器=新的ArrayList();
int totalPages=0;
//迭代器迭代器DFS=pdfs.Iterator();
迭代器迭代器DFS=pdfStreams.Iterator();
//为PDF创建读卡器。
while(iteratorPDFs.hasNext()){
InputStream pdf=iteratorPDFs.next();
如果(pdf==null)
继续;
PdfReader PdfReader=新PdfReader(pdf);
readers.add(pdfReader);
totalPages+=pdfReader.getNumberOfPages();
}
//清除这个
pdfStreams=null;
//WeakReference ref=新的WeakReference(PDF);
//参考clear();
//为outputstream创建写入程序
PdfWriter writer=PdfWriter.getInstance(文档,mergedPdfStream);
writer.setFullCompression();
document.open();
BaseFont bf=BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252,BaseFont.NOT_EMBEDDED);
PdfContentByte cb=writer.getDirectContent();//保存PDF文件
//资料
PDF导入页面;
int currentPageNumber=0;
int pageOfCurrentReaderPDF=0;
Iterator IteratorPDReader=readers.Iterator();
//循环浏览PDF文件并添加到输出中。
while(iteratorPDReader.hasNext()){
PdfReader PdfReader=iteratorpdfreeader.next();
//在目标中为每个源页面创建一个新页面。
而(pageOfCurrentReaderPDF
谢谢
V100个文件*500KB大约是50MB。如果最大堆大小是64MB,我很确定这段代码在这种情况下不会工作 100个文件*500KB大约是50MB。如果最大堆大小是64MB,我很确定这段代码在这种情况下不会工作 此代码将所有PDF合并到内存(堆)中的一个数组中,因此是的,内存使用量将随着合并的文件数线性增长 我不知道freeReader的方法,但也许你可以尝试将合并后的PDF写入一个临时文件,而不是字节数组
mergedPdfStream
将是FileOutputStream
而不是ByteArrayOutputStream
。然后返回对客户端代码的引用,例如文件
或者您可以增加Java可以使用的内存量(
-Xmx
JVM参数),但是如果要合并的文件数量最终增加,您将发现自己也会遇到同样的问题。此代码将所有PDF合并到内存(堆)中的数组中,所以是的,内存使用量将随着合并的文件数线性增长
我不知道freeReader的方法,但也许你可以尝试将合并后的PDF写入一个临时文件,而不是字节数组mergedPdfStream
将是FileOutputStream
而不是ByteArrayOutputStream
。然后返回对客户端代码的引用,例如文件
或者您可以增加Java可以使用的内存量(
-Xmx
JVM参数),但是如果要合并的文件数量最终增加,您将发现自己也会遇到同样的问题。首先,为什么要用所有迭代器样板代码来混乱您的代码?
你听说过for
语句吗?
i、 e
请尽快关闭PDFRADADER。这将有望刷新一些缓冲区并释放原始PDF占用的内存。首先,为什么要用这些迭代器样板代码来混乱代码? 你听说过
for
语句吗?
i、 e
请尽快关闭PDFRADADER。这可能会刷新一些缓冲区并释放原始PDF占用的内存。这不是执行文件操作的正确方法。你在做梅格
for (PDfReader pdfReader: readers) {
// code for each single PDF reader in readers
}