ITextSharp занимает слишком много времени для получения количества страниц - PullRequest
0 голосов
/ 13 октября 2011

У меня есть этот кусок кода:

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 ]

1 голос
/ 14 октября 2011

Определенно делайте то, что сказал @ChrisBint, чтобы преодолеть медлительность Window с папками с большим количеством файлов.

Но чтобы получить еще большую скорость, обязательно используйте перегрузку PdfReader, которая вместо этого принимает объект RandomAccessFileOrArray. Этот объект способ быстрее, чем обычные потоки во всех моих тестах. Конструктор имеет несколько перегрузок, но вы должны в основном заботиться о RandomAccessFileOrArray(string filename, bool forceRead). Второй параметр - загружать весь файл в память или нет (если я правильно понимаю документацию). Для очень больших файлов это может сказаться на производительности, но на современных машинах это не должно иметь большого значения, поэтому я рекомендую передать true. Если вы передадите false, диск нужно будет нажимать несколько раз, когда «курсор» разбора проходит по файлу.

Итак, со всем этим вы можете сделать это в очень тесной петле. Для меня 4000 файлов, содержащих более 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));
0 голосов
/ 13 октября 2011

Лично я бы немного изменил ваш код, чтобы не вызывать Directory.EnumerateFiles в foreach. Например;

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

Я сомневаюсь, что это сильно повлияет на общее время, если таковое будет

Насколько скорость вызывать свойство NumberOfPages. Маловероятно, что вы сможете оптимизировать это из-за того, что находитесь внутри объекта pdfReader. Если производительность является проблемой, то это может потребовать дополнительного оборудования.

Лично я бы не стал рассматривать это как проблему, если бы мне не пришлось постоянно запускать сканирование (в этом случае я бы начал смотреть на кэширование / проверку существующих файлов и только добавление тех, которые были изменены / новые).

...