PdfPage.flush() 的行为

behavior of PdfPage.flush()

PdfPage.flush(true) 到底有什么作用? SmartMode(或任何其他设置)是否影响行为?在很多情况下,我希望尽可能长时间地让页面保持可编辑状态,所以从不担心 PDF 文档在内存中组装,直到 document.close()。但是当生成非常大的文件(数万页)时,内存就会变得有限。我天真地希望 PdfPage.flush(true) 将内容流写入磁盘并释放内存,但调用 flush(true) 似乎只将几个字节写入磁盘。

我想我的问题的更一般版本是 "how do we efficiently merge lots of documents into a single, very-large document? (itext7)" 但不是非常精通 PDF 规范本身我也想更好地了解实际发生的事情。

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) 进行multi-stage批处理:在步骤X中将10个文件合并为1个,继续在步骤X+1中合并这些文件。一般来说,1个big-file会比单独的10个文件小,因为可能re-use字体和图片等资源

3) 运行 合并过程有时占用的资源在其他任何地方都不需要,例如,在晚上、午餐时间等。

编辑: 至于为什么 PdfPage#flush() 只向内容流写入几个字节,这取决于输入文档,但它很可能指向被刷新的页面,该页面要么主要包含文本内容,要么包含大量共享资源。 SmartMode 应该限制写入页面刷新的输出流的数量,只要该页面包含之前已复制的资源。