разделить огромный 40000 страниц PDF на отдельные страницы, itextsharp, outofmemoryexception - PullRequest
13 голосов
/ 09 августа 2011

Я получаю огромные PDF-файлы с большим количеством данных. Текущий PDF - 350 МБ и около 40000 страниц. Конечно, было бы неплохо получить PDF-файлы меньшего размера, но сейчас я должен работать с этим: - (

Я могу открыть его в Acrobat Reader с некоторой задержкой при загрузке, но после этого Acrobat Reader работает быстро.

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

Вот мой очень маленький код, использующий itextsharp:

var inFileName = @"huge350MB40000pages.pdf";
PdfReader reader = new PdfReader(inFileName);
var nbrPages = reader.NumberOfPages;
reader.Close();

Что происходит, когда дело доходит до второй строки "new PdfReader", затем остается там, возможно, 10 минут, процесс достигает примерно 1,7 ГБ, и затем я получаю исключение OutOfMemoryException.

Я думаю, что "новый PdfReader" пытается прочитать весь PDF в память.

Есть ли другой / лучший способ сделать это? Например, могу ли я как-то прочитать только часть файла PDF в память, а не все сразу? Может ли он работать лучше с использованием какой-нибудь другой библиотеки, чем itextsharp?

Ответы [ 5 ]

16 голосов
/ 09 августа 2011

Из того, что я прочитал, при создании экземпляра PdfReader выглядит, что вы должны использовать конструктор, который принимает объект RandomAccessFileOrArray. Отказ от ответственности: я не пробовал это сам.

iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(new iTextSharp.text.pdf.RandomAccessFileOrArray(@"C:\PDFFile.pdf"), null);
4 голосов
/ 09 августа 2011

Это полный выстрел в темноте, и я не тестировал этот код - это фрагмент кода из книги «iText In Action», который приводится в качестве примера того, как обращаться с большими файлами PDF.Код написан на Java, но его довольно легко конвертировать -

Это метод, который загружает все в память -

PdfReader reader;
long before;
before = getMemoryUse();
reader = new PdfReader(
"HelloWorldToRead.pdf", null);
System.out.println("Memory used by the full read: "
+ (getMemoryUse() - before));

Это способ экономии памяти, где документ должен бытьзагружается побитно по мере необходимости -

before = getMemoryUse();
reader = new PdfReader(
new RandomAccessFileOrArray("HelloWorldToRead.pdf"), null);
System.out.println("Memory used by the partial read: "
+ (getMemoryUse() - before));
0 голосов
/ 15 августа 2011

Может ли он работать лучше с использованием какой-либо другой библиотеки, чем itextsharp?

Пожалуйста, попробуйте Aspose.Pdf для .NET , который позволяет разбить PDF на отдельные страницы или вы можете разбить PDF на разные наборы страниц различными способами, используя файлы или потоки памяти. API очень прост в освоении и использовании. Он работает с большими файлами PDF, имеющими большое количество страниц.

Раскрытие информации: я работаю евангелистом-разработчиком в Aspose.

0 голосов
/ 12 августа 2011

PDF Toolkit весьма полезен для задач такого типа.Пока еще не пробовал с таким огромным файлом.

0 голосов
/ 09 августа 2011

Возможно, вы сможете использовать Ghostscript напрямую. http://svn.ghostscript.com/ghostscript/tags/ghostscript-9.02/doc/Use.htm#One_page_per_file

Для чтения данных получателя хорошим выбором может быть pdftextstream.

...