微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么尾部对象报告“尺寸”条目的先前值?

如何解决为什么尾部对象报告“尺寸”条目的先前值?

我正在尝试编写代码,以对签名后的PDF文档的更改进行调查(欢迎使用指针),并遇到了这个奇怪的问题。

我想检索xref表中索引的PDF文件中的对象数。看来,尽管预告片字典中的所有其他条目都是最终预告片的条目,但Size的数字是原始预告片上的数字。在我的特殊情况下,原始文档进行了2次更新(添加了2个外部参照表,总共3个),从原始对象550个开始增加了对象,数量达到567个。

这是我从预告字典中获得Size的方式:

  private static long getMaxObjId(PDDocument doc) {
    COSDocument cosdoc = doc.getDocument();
    COSDictionary trailer = cosdoc.getTrailer();
    long maxobj = trailer.getLong(COSName.SIZE);
    return maxobj;
  }

我正在使用PDFBox 2.0.21。

解决方法

您是对的。该预告片中的 Size 条目包含以下所有预告片中最低(即通常是最旧的 Size 值文档,而该 trailer 中的所有其他条目都包含其各自键的最新值。

导致这种情况的原因甚至比我最初想的还要糟糕:您获得的 trailer 对象不仅仅是最新的(或者考虑到 Size 值, )文档中的 trailer 词典,它是所有 trailer 词典的并集,从 Prev 链中最早的预告片开始,一直到最新一个。

到目前为止一切顺利。但这是否不意味着该联合预告片中的所有条目都应具有最新的 trailer 词典中的值以及输入键?这就是我一直想的,直到我看到用来创建该联合的COSDictionary.addAll(COSDictionary)代码:

/**
 * This will add all of the dictionaries keys/values to this dictionary.
 * Only called when adding keys to a trailer that already exists.
 *
 * @param dic The dictionaries to get the keys from.
 */
public void addAll(COSDictionary dic)
{
    dic.forEach((key,value) ->
    {
        /*
         * If we're at a second trailer,we have a linearized pdf file,meaning that the first Size entry represents
         * all of the objects so we don't need to grab the second.
         */
        if (!COSName.SIZE.equals(key) || !items.containsKey(COSName.SIZE))
        {
            setItem(key,value);
        }
    });
}

此处明确不替换现有的 Size 项!

这解释了最初的观察结果,即预告片中的 Size 条目包含最低(即通常是最旧 Size 值,而该预告片中的所有其他条目包含其各自键的最新值。

这些评论引起这样的假设,即从默认情况下PDFBox从头开始解析PDF时就忽略了交叉引用表,而只有相关的测试PDF是没有常规增量更新的,只是没有完全使用线性化进行更新,线性化使用为反向更新定义的增量更新机制。而且只有在这种线性化文档的情况下,这种例外才有意义。

但是为什么我认为这比最初的设想更糟:此addAll方法是公用的COSDictionary方法,其名称与Java Collection Framework addAll相似。因此,它使用户认为第一JavaDoc行This will add all of the dictionaries keys/values to this dictionary是真实的;因此他将用它来完成该任务,从不希望 Size 条目不会被替换。

实际上,即使在第二个JavaDoc行COSDictionary.addAll(COSDictionary)中,即使在PDFBox代码本身中,Only called when adding keys to a trailer that already exists.仍在用于拖车联合的其他上下文中使用

应检查并修复。为此,我创建了一个Jira问题,PDFBOX-4999

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。