我想知道这已经有一段时间了。 PdfReader中有两个调用来获取页面字典:getPageN()和getPageNRelease()。

在什么情况下我们应该使用其中一个?

两者对性能有影响吗?

例如,我有一种算法,该算法将迭代现有PDF中的每一页并从中读取数据。我应该使用哪个电话?

最佳答案

首先,如果您想更改检索到的页面对象,并希望该更改不是易变的(例如出现在PdfStamper的输出中,您将应用到有问题的PdfReader中),则应使用getPageN()。如果仅检索页面以从中读取信息,则应使用getPageNRelease()

有什么区别?好吧,首先,只有在部分模式下运行PdfReader实例的情况下,这才有所不同,即,它在启动时未解析整个PDF,而仅解析了有关PDF的基本理解所需的那些对象。否则,即,如果PDF已被完全解析,则这两种方法都可以有效地进行相同操作。

如果以这种模式工作,

  • 使用PdfReader.getPageN()检索的页面被添加到内部缓存中;因此,如果稍后再次查询同一页面,则将检索相同的对象,包括已应用的所有更改,在此阅读器上操作的PdfStamper也会如此;
  • ,但检索后立即使用PdfReader.getPageNRelease()检索的页面再次从该缓存中删除(除非该页面之前已经被检索并添加到该缓存中)。

  • 这样做是因为您通常使用部分模式来最小化内存中PDF的部分。因此,如果检索页面只是为了从页面中读取内容,则页面中包含的对象可以在读取完所需信息后立即再次从内存中删除。

    但是,请不要指望通过PdfReader.getPageNRelease()读取的页面是易失的:不是没有使用部分模式,不是在使用PdfReader.getPageN()之前已经检索过页面,还是在之前已经调用PdfReader.setTampered()

    可以通过使用以下构造函数之一来激活部分模式
    public PdfReader(final RandomAccessFileOrArray raf, final byte ownerPassword[]) throws IOException
    
    public PdfReader(final RandomAccessFileOrArray raf, final byte ownerPassword[], boolean partial)
    
    public PdfReader(final String filename, final byte ownerPassword[], boolean partial) throws IOException
    

    (在后两种情况下)和partial参数值true。没有其他构造函数允许选择部分模式。

    OP在评论中要求

    我们正在使用部分模式。 getPageN()之后再调用reader.releasePage()是否具有相同的效果?

    也许吧。

    ,因为getPageNRelease()是这样实现的
    public PdfDictionary getPageNRelease(final int pageNum) {
        PdfDictionary dic = getPageN(pageNum);
        pageRefs.releasePage(pageNum);
        return dic;
    }
    

    releasePage()这样
    public void releasePage(final int pageNum) {
        pageRefs.releasePage(pageNum);
    }
    

    因此,getPageNRelease()实际上与getPageNreleasePage()相同。

    也许是,因为在这些方法调用之间您不应等待太长时间。特别是,您不应同时请求另一个页面,因为只能释放最近获取的页面。

    10-02 10:20