1

大多数 iText7 示例都提到使用PdfFontFactory.createFont()来获取 PdfFont 实例的句柄以进行文本操作。适度,这很好......但是 PdfFont 是一个相当重量级的对象(PdfEncoding),在 PdfDocument 关闭之前它似乎不会消失。所以下面这个无辜的块会吞噬内存:

for (int i = 0; i < someLargeNumber; i++) {
    list.add(
        new ListItem("never gonna give")
        .setFont(PdfFontFactory.createFont("Helvetica-Oblique"))
    )
}

使用静力学解决方案的一次简单尝试失败了,因为似乎 PdfFont 实例不能在多个 PdfDocument 中使用。而且因为我的实际情况比上面的例子更复杂,我不想在一个相当深的堆栈中传递一堆 PdfFont 引用。

  1. 在 iText7 API 中,无法迭代 PdfDocument 的现有 PdfFont(有吗?)
  2. 是 PdfFont 使用的简单规则,即 a) 它可以根据需要多次使用 b) 在单个 PdfDocument 实例中

(也就是说,这里有一个可能的解决方案是使用 PdfDocument + PdfFontProgram 键简单地缓存 PdfFont 实例?)

4

1 回答 1

0

PdfFonts 似乎在 PdfDocument 级别是可缓存/可重用的。如果使用 Wea​​kHashMap 作为缓存,Keys 和 Values 都需要是弱引用。例如

private static WeakHashMap<PdfDocument, Map<String, WeakReference<PdfFont>>> fontCache = new WeakHashMap<>();

public static synchronized PdfFont createFont(PdfDocument forDocument, String path) throws IOException {
    Map<String, WeakReference<PdfFont>> documentFontMap = fontCache.get(forDocument);
    if (documentFontMap == null) {
        documentFontMap = new HashMap<>();
        fontCache.put(forDocument, documentFontMap);
    }
    WeakReference<PdfFont> font = documentFontMap.get(path);
    if (font == null) {
        font = new WeakReference<>(PdfFontFactory.createFont(path));
        documentFontMap.put(path, font);
    }
    return font.get();
}

还应注意调用 PdfFontFactory 本身的 iText API,例如配置为显示人类可读值的 Barcode1D 衍生工具(即,在不调用 setFont() 的情况下为每页创建一个新的 Barcode1D 实例将很快耗尽大型文档的内存)

于 2016-08-11T14:01:03.177 回答