ITextSharp在获取页数方面花费了太多时间

时间:2011-10-13 14:46:02

标签: performance pdf c#-4.0 itextsharp

我有这段代码:

foreach(string pdfFile in Directory.EnumerateFiles(selectedFolderMulti_txt.Text,"*.pdf",SearchOption.AllDirectories))
{
    //filePath = pdfFile.FullName;
    //string abc = Path.GetFileName(pdfFile);
    try
    {
        //pdfReader = new iTextSharp.text.pdf.PdfReader(filePath);
        pdfReader = new iTextSharp.text.pdf.PdfReader(pdfFile);
        rownum = pdfListMulti_gridview.Rows.Add();
        pdfListMulti_gridview.Rows[rownum].Cells[0].Value = counter++;
        //pdfListMulti_gridview.Rows[rownum].Cells[1].Value = pdfFile.Name;
        pdfListMulti_gridview.Rows[rownum].Cells[1].Value = System.IO.Path.GetFileName(pdfFile);
        pdfListMulti_gridview.Rows[rownum].Cells[2].Value = pdfReader.NumberOfPages;
        //pdfListMulti_gridview.Rows[rownum].Cells[3].Value = filePath;
        pdfListMulti_gridview.Rows[rownum].Cells[3].Value = pdfFile;
        //totalpages += pdfReader.NumberOfPages;
    }
    catch
    {
        //MessageBox.Show("There was an error while opening '" + pdfFile.Name + "'", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
        MessageBox.Show("There was an error while opening '" + System.IO.Path.GetFileName(pdfFile) + "'", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

问题是,今天我指定了一个包含大约4000个pdf文件的文件夹,大约花了20分钟阅读所有文件并向我显示结果。然后,我想当我输入一个包含20,000多个文件的文件夹时,这段代码会做什么。

如果我注释掉这一行:

pdfListMulti_gridview.Rows[rownum].Cells[2].Value = pdfReader.NumberOfPages;

然后,似乎从代码中删除了所有处理负担。

所以,我想要你们的建议是让我的方法更有效率,并且应该花更少的时间来处理所有文件。或者有其他选择吗?

2 个答案:

答案 0 :(得分:1)

绝对要做@ChrisBint所说的,这将会超过Window的文件包含很多文件的速度。

但为了获得更高的速度,请确保使用PdfReader的重载代替RandomAccessFileOrArray对象。在我的所有测试中,此对象比常规流更快方式。构造函数有两个重载,但你应该主要关注RandomAccessFileOrArray(string filename, bool forceRead)。第二个参数是是否将整个文件加载到内存中(如果我正确理解文档)。对于非常大的文件,这可能是性能损失,但在现代机器上它应该没什么关系,所以我建议你将true传递给它。如果你传递false,那么当解析“光标”遍历文件时,需要多次点击磁盘。

所以,所有这些都可以在非常紧凑的循环中完成。对我来说,包含总计超过42,000页的4,000个文件大约需要2秒钟才能运行。

        var files = Directory.EnumerateFiles(workingFolder, "*.pdf");
        int totalPageCount = 0;
        foreach (string f in files)
        {
            totalPageCount += new PdfReader(new RandomAccessFileOrArray(f, true), null).NumberOfPages;
        }
        MessageBox.Show(String.Format("Total Page Count : {0:N0}", totalPageCount));

答案 1 :(得分:0)

就个人而言,我会略微更改您的代码,而不是在foreach中调用Directory.EnumerateFiles。例如;

var listOfFiles = Directory.EnumerateFiles(selectedFolderMulti_txt.Text,"*.pdf",SearchOption.AllDirectories);
foreach(string pdfFile in listOfFiles)
{
//Do something
}

我怀疑这会对整个时间造成大量影响,如果有的话。

调用NumberOfPages属性的速度。由于pdfReader对象是内部的,因此您不太可能优化它。如果考虑性能,则可能需要额外的硬件。

就个人而言,我不会将此视为一个问题,除非我必须不断运行扫描(在这种情况下,我会开始查看缓存/检查现有文件,只添加已更改/新文件)。