目前我正在使用 itext 来读取 pdf 的页数。这需要很长时间,因为库似乎扫描整个文件。
页面信息是否位于 pdf 标题中的某个位置,或者是否需要完整的文件扫描?
是的。 iText 在打开时解析相当多的 PDF(它不读取流对象的内容,但仅此而已)...
除非您使用
PdfReader(RandomAccessFileOrArray)
构造函数,在这种情况下,它只会读取外部参照(大部分是必需的),但不会解析任何内容,直到您开始请求特定对象(直接或通过各种调用)。
我编写的第一个 PDF 程序正是这样做的。 它打开一个 PDF 并执行最少的必要工作,读取页数。 它甚至没有解析它不需要的外部参照。 已经很多年没有想过这个计划了...
因此,虽然效率不高,但使用 RandomAccessFileOrArray 会更加更高效:
int efficientPDFPageCount(String path) {
RandomAccessFileOrArray file = new RandomAccessFileOrArray(path, false, true );
PdfReader reader = new PdfReader(file);
int ret = reader.getNumberOfPages();
reader.close();
return ret;
}
更新:
itext API 进行了一些修改。现在(在版本 5.4.x 中)正确的使用方法是通过 java.io.RandomAccessFile:
int efficientPDFPageCount(File file) {
RandomAccessFile raf = new RandomAccessFile(file, "r");
RandomAccessFileOrArray pdfFile = new RandomAccessFileOrArray(
new RandomAccessSourceFactory().createSource(raf));
PdfReader reader = new PdfReader(pdfFile, new byte[0]);
int pages = reader.getNumberOfPages();
reader.close();
return pages;
}
您只需要阅读页面树(目录、页面、儿童)并计算页面条目数。
在 iText 版本 5.5.13 中,以下方法将为您提供页码,而无需扫描整个文件。它不会将完整的文件内容读入内存。
int efficientPDFPageCount(String filePath){
PdfReader reader = new PdfReader(filePath, new byte[0], true);
int pages = reader.getNumberOfPages();
reader.close();
return pages;
}
PdfReader document = new PdfReader(new FileInputStream(new File("filename")));
int noPages = document.getNumberOfPages();
PdfReader document = new PdfReader(new FileInputStream(new File("filename")));
int noPages = document.getNumberOfPages();
以上是统计pdf页数的过程