2017-01-03 8 views
0

Я пытаюсь объединить 2 больших файла PDF, не загружая их полностью в память.Как объединить огромные файлы PDF, не загружая их полностью в память с помощью itext 7?

Я попытался с PdfMerger и вручную без PdfMerger благодаря такому коду:

using(var writer = new PdfWriter(new FileStream(@"C:\Test\OutBig.pdf",FileMode.OpenOrCreate))) 
    using (var outputDocument = new PdfDocument(writer)) { 
     using (var inputDoc = new PdfDocument(new PdfReader((@"C:\Test\InBig.pdf")))) { 
      for (int i = 1; i <= inputDoc.GetNumberOfPages(); i++) { 
       var newp = outputDocument.AddNewPage(); 
       var canvas = new PdfCanvas(newp); 
       var origPage = inputDoc.GetPage(i); 
       var copy = origPage.CopyAsFormXObject(outputDocument); 
       canvas.AddXObject(copy, 0, 0); 
       copy.Flush(); 
       origPage = null; 
       canvas.Release(); 
       newp.Flush(); 
       writer.Flush(); 
       canvas = null; 
       newp = null; 
      } 
     } 

код работает, но каждая страница загружается в памяти и оставаться загруженной, и я, следовательно, имею более 1 Гб загружен в память.

Знаете ли вы, что хотите объединить 2 pdf-файла без их загрузки в память с помощью itext7?

С уважением,

Patrice

+0

Вы используете 'CopyAsFormXObject' и' AddXObject' для слияния по определенной причине? Вместо «PdfDocument.CopyPagesTo» я имею в виду. – mkl

+0

Даже когда я меняю свой код на использование метода CopyPagesTo, все загружается в память. InputDoc хранит в памяти все. – PatriceVB

+0

Хорошо, мне просто интересно, потому что merge-by-XObject обычно крайне нежелателен. Это было сказано, я еще не тестировал голод памяти iText 7, но я мог бы взять это как начало для изучения ... – mkl

ответ

1

Там находятся несколько способов снижения потребления памяти при копировании больших документов с iText7. Один из них заключается в том, чтобы использовать тот факт, что объекты читаются по требованию. Таким образом, вы фактически можете копировать страницы из исходного документа в документ назначения несколькими партиями, открывая и закрывая исходный документ несколько раз.

Вот код на Java, который должен преобразовываться в C# почти исключительно путем замены имен методов на верхний регистр.

PdfDocument doc1 = new PdfDocument(new PdfReader(IN1)); 
int numOfPages = doc1.getNumberOfPages(); 
doc1.close(); 
PdfDocument outDoc = new PdfDocument(new PdfWriter(OUT)); 
int numOfPagesPerDocumentOpen = 10; 
for (int i = 1; i <= numOfPages;) { 
    int firstPageToCopy = i; 
    int lastPageToCopy = Math.min(i + numOfPagesPerDocumentOpen - 1, numOfPages); 
    doc1 = new PdfDocument(new PdfReader(IN1)); 
    doc1.copyPagesTo(firstPageToCopy, lastPageToCopy, outDoc); 
    // Flush last lastPageToCopy - firstPageToCopy + 1 pages 
    for (int j = 0; j <= lastPageToCopy - firstPageToCopy; j++) { 
     outDoc.getPage(outDoc.getNumberOfPages() - j).flush(true); 
    } 
    doc1.close(); 
    i = lastPageToCopy + 1; 
} 
outDoc.close();