iText 的 getPageN() 和 getPageNRelease() 调用有什么区别?
What is the difference between iText's getPageN() and getPageNRelease() calls?
我想知道这个问题有一段时间了。 PdfReader 中有两个获取页面字典的调用:getPageN() 和 getPageNRelease()。
在什么情况下我们应该使用其中一种?
两者对性能有影响吗?
例如,我有一个算法可以迭代现有 PDF 中的每一页并从中读取数据。我应该使用哪个电话?
主要是,如果您想更改检索到的页面对象,希望更改不会易变(但要出现在 PdfStamper
的输出中,您将应用于 PdfReader
问题),你应该使用 getPageN()
。如果检索页面只是为了从中读取信息,则应使用 getPageNRelease()
.
有什么区别? 好吧,首先,如果你在部分模式下有一个 PdfReader
实例 运行,那么只有区别,即,如果它在启动时没有解析整个 PDF,而是只解析基本理解所讨论的 PDF 所需的那些对象。否则,即如果 PDF 已被完全解析,则两种方法有效地执行相同的操作。
如果在此模式下工作,
- 您使用
PdfReader.getPageN()
检索的页面被添加到内部缓存;因此,如果您稍后再次查询同一页面,您将检索到相同的对象,包括您应用的所有更改,PdfStamper
在此 reader; 上操作也是如此
- 但是您在检索后立即使用
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
。没有其他构造函数允许 select 部分模式。
OP 在评论中提问
we are using partial mode. Does getPageN() followed later by a call to reader.releasePage() have the same effect?
是的,也许。
是,因为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()
实际上等同于 getPageN
加上 releasePage()
。
可能,因为您不应在这些方法调用之间等待太久。特别是您不应同时请求另一个页面,因为只能释放最近获取的页面。
我想知道这个问题有一段时间了。 PdfReader 中有两个获取页面字典的调用:getPageN() 和 getPageNRelease()。
在什么情况下我们应该使用其中一种?
两者对性能有影响吗?
例如,我有一个算法可以迭代现有 PDF 中的每一页并从中读取数据。我应该使用哪个电话?
主要是,如果您想更改检索到的页面对象,希望更改不会易变(但要出现在 PdfStamper
的输出中,您将应用于 PdfReader
问题),你应该使用 getPageN()
。如果检索页面只是为了从中读取信息,则应使用 getPageNRelease()
.
有什么区别? 好吧,首先,如果你在部分模式下有一个 PdfReader
实例 运行,那么只有区别,即,如果它在启动时没有解析整个 PDF,而是只解析基本理解所讨论的 PDF 所需的那些对象。否则,即如果 PDF 已被完全解析,则两种方法有效地执行相同的操作。
如果在此模式下工作,
- 您使用
PdfReader.getPageN()
检索的页面被添加到内部缓存;因此,如果您稍后再次查询同一页面,您将检索到相同的对象,包括您应用的所有更改,PdfStamper
在此 reader; 上操作也是如此
- 但是您在检索后立即使用
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
。没有其他构造函数允许 select 部分模式。
OP 在评论中提问
we are using partial mode. Does getPageN() followed later by a call to reader.releasePage() have the same effect?
是的,也许。
是,因为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()
实际上等同于 getPageN
加上 releasePage()
。
可能,因为您不应在这些方法调用之间等待太久。特别是您不应同时请求另一个页面,因为只能释放最近获取的页面。