Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java pdf合并期间的OutOfMemoryError_Java_Pdf_Merge_Itext - Fatal编程技术网

Java pdf合并期间的OutOfMemoryError

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,

下面的代码合并pdf文件并返回组合的pdf数据。当代码运行时,我尝试将100个文件与每个大约500kb的文件组合在一起,但在行文档.close()中出现了outofmemory错误;。此代码在web环境中运行,内存是否可用于web服务器?问题出在哪里?我在一篇文章中读到使用freeReader方法,但我不知道如何在我的场景中使用它

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
谢谢
V

100个文件*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
}