поведение PdfPage.flush ()

что именно делает PdfPage.flush (true)? Влияет ли SmartMode (или любой другой параметр) на поведение? Во многих случаях я хочу, чтобы страница оставалась редактируемой как можно дольше, поэтому не беспокойтесь о том, что документ PDF был собран в памяти до document.close(). Но при создании очень больших файлов (десятки тысяч страниц) объем памяти становится ограниченным. Я наивно надеялся, что PdfPage.flush(true) запишет поток контента на диск и освободит память, но вызов flush(true), похоже, записывает на диск только пару байтов.

Я предполагаю, что более общая версия моего вопроса: «Как нам эффективно объединить множество документов в один, очень большой документ? (Itext7)», но не будучи высокопрофессиональным с самой спецификацией PDF, я также хотел бы лучше понять, что на самом деле происходит.


person jamey graham    schedule 12.01.2017    source источник


Ответы (1)


flush(), когда вызывается для объектов макета, заставляет эти объекты и их дочерние элементы рисовать (== записывать) свое содержимое в выходной поток писателя. Причина, по которой при ручном вызове flush () записывается только пара байтов, заключается в том, что конструкторы по умолчанию Document уже установили iText для агрессивного сброса путем перегрузки соответствующих конструкторов:

/**
 * Creates a document from a {@link PdfDocument} with a manually set {@link
 * PageSize}.
 *
 * @param pdfDoc   the in-memory representation of the PDF document
 * @param pageSize the page size
 */
public Document(PdfDocument pdfDoc, PageSize pageSize) {
    this(pdfDoc, pageSize, true);
}

/**
 * Creates a document from a {@link PdfDocument} with a manually set {@link
 * PageSize}.
 *
 * @param pdfDoc         the in-memory representation of the PDF document
 * @param pageSize       the page size
 * @param immediateFlush if true, write pages and page-related instructions
 *                       to the {@link PdfDocument} as soon as possible.
 */
public Document(PdfDocument pdfDoc, PageSize pageSize, boolean immediateFlush)

Что касается совета по общему вопросу: на самом деле нет какой-то функции или конфигурации iText, которая бы волшебным образом делала весь процесс быстрее и эффективнее, но есть некоторые уловки, которые вы можете сделать за пределами iText:

1) Выделить больше ресурсов, очевидно и часто неосуществимо.

2) Выполните многоступенчатую пакетную обработку: объедините 10 файлов в 1 на этапе X, продолжите объединение этих файлов на этапе X + 1. В общем, 1 большой файл будет меньше, чем 10 файлов по отдельности из-за возможного повторного использования ресурсов, таких как шрифты и изображения.

3) Запускайте процесс слияния, когда ресурсы, которые он занимает, больше нигде не нужны, например, ночью, во время обеда и т. Д.

Изменить: что касается того, почему PdfPage # flush () записывает только пару байтов в поток содержимого, это зависит от входного документа, но, скорее всего, указывает на сбрасываемую страницу, которая либо имеет в основном текстовое содержимое, либо много общих ресурсов. SmartMode должен ограничивать количество записываемых в выходной поток, очищаемый страницей, если страница содержит ресурсы, которые были скопированы ранее.

person Samuel Huylebroeck    schedule 18.01.2017
comment
для ясности, я вижу только пару байтов, записанных ВСЕГО (т.е. немедленныйFlush не делает ничего проще ... весь выходной файл имеет длину всего пару байтов вместо Мб) . Я ценю попытку ответа, но не думаю, что он отвечает на мой PdfPage.flush(boolean flushContentStream) вопрос. Пытаясь проследить путь кода до PdfObject.flush (), похоже, может быть другое поведение с очисткой косвенных ссылок (но я не могу сшить все вместе в своей голове). - person jamey graham; 18.01.2017
comment
@jameygraham для ясности, ... - вам действительно стоит обновить вопрос, поскольку в настоящее время он, похоже, говорит что-то другое. И если в результирующем PDF-файле всего несколько байтов, я бы предположил, что процедура либо остановлена ​​из-за исключения, либо ваш код делает что-то не так, например, захват PDF-файла до закрытия PdfDocument. - person mkl; 19.01.2017
comment
@jameygraham Я попытался ответить на ваш первоначальный вопрос о PdfPage.flush. Однако в ядре есть некоторые сложные взаимодействия из-за различных оптимизаций, поэтому я, возможно, пропустил некоторые вещи. Если вы объединяете большие файлы, и ваш результат составляет всего пару байтов, у вас может быть совсем другая проблема. Возможно, поскольку эти 1000-страничные файлы могут быть ужасно неэффективными чудовищами, но без доступа как к вводу, так и к выводу, я больше не могу вам помочь. Тем не менее, мои общие замечания по второму, более общему вопросу все еще остаются в силе. - person Samuel Huylebroeck; 20.01.2017
comment
@samuel - хорошо ... похоже, есть ожидание, что сброс страницы должен на самом деле записывать поток (-ы) содержимого страницы на диск (что не является поведением, которое я наблюдаю) . Если это правда, это само по себе кажется достаточным, чтобы ответить на мой вопрос (я действительно был немного сбит с толку из-за изменения имени параметра .... с того, что я думаю, было flush(boolean flushXObjects) [700] на flush(boolean contentStreams) [701]). Я расскажу об обращении в службу поддержки на конкретном примере. - person jamey graham; 20.01.2017