5

我正在尝试通过 iText 合并 1000 个 PDF 文件。我不确定内存泄漏发生在哪里。下面是示例代码。请注意,一旦我合并到父文件,我就会删除子 PDF 文件。请指出下面代码中的错误,或者有没有更好的方法可以在没有内存概念的情况下做到这一点。这个过程是通过 servlet(不是独立程序)完成的

FileInputStream local_fis = null;
BufferedInputStream local_bis = null;
File localFileObj = null;
for(int taIdx=0;taIdx<totalSize;taIdx++){
    frObj = (Form3AReportObject)reportRows.get(taIdx);
    localfilename = companyId + "_" +  frObj.empNumber + ".pdf";

    local_fis = new FileInputStream(localfilename);
    local_bis = new BufferedInputStream(local_fis); 
    pdfReader = new PdfReader(local_bis);

    cb = pdfWriter.getDirectContent(); 
    document.newPage();
    page = pdfWriter.getImportedPage(pdfReader, 1);
    cb.addTemplate(page, 0, 0);
    local_bis.close();
    local_fis.close();

    localFileObj = new File(localfilename);
    localFileObj.delete();
}
document.close();
4

7 回答 7

8

您可能想尝试以下操作(为清楚起见,异常处理、文件关闭和删除删除):

for(int taIdx = 0; taIdx < totalSize; taIdx++) {
    Form3AReportObject frObj = (Form3AReportObject)reportRows.get(taIdx);

    localfilename = companyId + "_" +  frObj.empNumber + ".pdf";

    FileInputStream local_fis = new FileInputStream(localfilename);

    pdfWriter.freeReader(new PdfReader(local_fis));

    pdfWriter.flush();
}

pdfWriter.close();
于 2009-08-12T04:37:31.210 回答
1

谁说有内存泄漏?您的合并文档需要完全放入内存中,没有办法绕过它,而且它很可能大于内存中的默认堆大小 64MB (而不是磁盘上)。

我看不出您的代码有问题,但是如果您想详细诊断它,请使用 visualvm 的堆分析器(自 Java 6 更新 10 左右以来随 JDK 一起提供)。

于 2009-08-11T15:08:58.147 回答
1
public class PdfUtils {
     public static void concatFiles(File file1, File file2, File fileOutput) throws Exception {
          List<File> islist =  new ArrayList<File>();
          islist.add(file1);
          islist.add(file2);

          concatFiles(islist, fileOutput);
         }

         public static void concatFiles(List<File> filelist, File fileOutput) throws Exception {
          if (filelist.size() > 0) {
                 PdfReader reader = new PdfReader(new FileInputStream( filelist.get(0)) );
                 Document document = new Document(reader.getPageSizeWithRotation(1));

           PdfCopy cp = new PdfCopy(document,  new FileOutputStream( fileOutput ));

           document.open();


           for (File file : filelist ) {

                PdfReader r = new PdfReader( new FileInputStream( file));
                for (int k = 1; k <= r.getNumberOfPages(); ++k) {
                    cp.addPage(cp.getImportedPage(r, k));
                }
                cp.freeReader(r);

           }
           cp.close();
           document.close();
          } else{             
           throw new Exception("La lista dei pdf da concatenare è vuota");        
          }               
         }
   }
于 2013-05-23T10:37:17.257 回答
0

您是否尝试过从默认值(仅为 64mb)增加最大堆大小?

看:

于 2009-08-11T15:00:48.987 回答
0

如果你不使用 InputStream 怎么办?如果可以,请尝试仅使用'new PDFReader("/somedirectory/file.") 上的文件路径。

这使读者对磁盘进行操作。

于 2012-12-17T13:13:15.687 回答
0

上面的代码试图在循环中创建一个PdfContentByte对象 ( )。cb把它移到外面可能会解决这个问题。我在我的应用程序中使用了类似的代码,将 13k 个单独的 PDF 拼接成一个 PDF,没有任何问题。

于 2013-03-19T17:55:18.573 回答
-2

不要合并 1000 个 PDF,而是尝试创建它们的 zip。

于 2012-11-28T11:28:43.923 回答