【问题标题】:ITextSharp taking too much time in getting Number of PagesITextSharp 在获取页数方面花费了太多时间
【发布时间】:2011-10-13 14:46:01
【问题描述】:

我有这段代码:

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;

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

所以,我想从你们那里得到一个建议,让我的方法更高效,并减少处理所有文件的时间。还是有其他选择?

【问题讨论】:

    标签: performance pdf c#-4.0 itextsharp


    【解决方案1】:

    绝对按照@ChrisBint 所说的去做,这将克服 Window 对包含许多文件的文件夹的缓慢影响。

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

    因此,您可以在一个非常紧凑的循环中执行此操作。对我来说,运行 4,000 个文件,总共超过 42,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));
    

    【讨论】:

    • 相同的旧处理时间。我想我将不得不坚持这种情况。我刚刚在您的代码中添加了“SearchOption.AllDirectories”。
    • @booota,我非常非常惊讶。您是否使用至少 1 或 2 GB 的 RAM 运行?您是否有任何非常大的 PDF,比如超过 200MB?
    • 哈哈。我有 2.5GB RAM 的 C2D 处理器。是的,所有文件都大约 9GB。单个文件最大为 15MB。但是使用另一个具有 9 GB 文件的文件夹(数量更多但大小更小)的时间要少一些。第一个文件夹大约有。 4000 个文件,第二个文件夹大约有 16000 个文件。我也对大约感到惊讶。两个文件夹的时间相同。我认为这是影响性能的文件大小问题
    • 对我来说肯定更快。谢谢。
    【解决方案2】:

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

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

    如果有的话,我怀疑这会极大地影响整体时间。

    就调用 NumberOfPages 属性的速度而言。由于 pdfReader 对象的内部,您不太可能对此进行优化。如果性能是一个问题,那么这可能需要额外的硬件。

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

    【讨论】:

    • 是的,我认为为了提高性能,我需要额外的硬件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2020-07-23
    • 2013-07-11
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多