цикл для файлов PDF - PullRequest
       7

цикл для файлов PDF

2 голосов
/ 24 ноября 2010

Моя программа переходит в каталог и ищет pdf-файлы для их анализа.Эта программа всегда запущена, поэтому я должен убедиться, что снова не проанализирую один и тот же файл.

Я использовал список для хранения имен файлов, а затем проверил, есть ли они там.

Мой код не работает в этом отношении, если кто-то может взглянуть и увидеть, что не так, это будет с благодарностью

FileInfo[] filePaths = di.GetFiles("*.pdf");
for (int i = 0; i < filePaths.Length; i++)
{
    foreach (string fileName in usedFileNames)
    {
        if (fileName.Equals(filePaths[i].Name))
        {
            isInList = true;
        }
        else
        {
            isInList = false;
        }
    }
    if (isInList == false)
    {
        PDFReaderChooser chooser = new PDFReaderChooser(filePaths[i].Name);
        usedFileNames.Add(filePaths[i].Name);
    }

}

Ответы [ 4 ]

4 голосов
/ 24 ноября 2010

Еще лаконичнее:

var fileNames = di.GetFiles("*.pdf")
                  .Select(f => f.Name)
                  .Where(n => !usedFileNames.Contains(n));
usedFileNames.AddRange(fileNames);

foreach (var fileName in fileNames)
{
    var chooser = new PDFReaderChooser(fileName);
}

Это прекрасно абстрагирует логику, которая определяет, какие имена файлов вам нужно обработать (вне цикла), от логики, которая их обрабатывает (внутри цикла).

3 голосов
/ 24 ноября 2010

Хотя другие ответы являются лучшим решением проблемы, они не объясняют, почему оригинальный код не работал. Проблема заключается в том, что алгоритм перезаписывает значение переменной isInList, которая, следовательно, будет верна только для последнего файла в списке. Это решило бы эту проблему:

FileInfo[] filePaths = di.GetFiles("*.pdf"); 
for (int i = 0; i < filePaths.Length; i++) 
{ 
    isInList = false
    foreach (string fileName in usedFileNames) 
    { 
        if (fileName.Equals(filePaths[i].Name)) 
        { 
            isInList = true;
            break;
        } 
    } 
    if (isInList == false) 
    { 
        PDFReaderChooser chooser = new PDFReaderChooser(filePaths[i].Name); 
        usedFileNames.Add(filePaths[i].Name); 
    } 
} 

Я бы добавил, что лучше использовать HashSet вместо List для вашей коллекции usedFileNames. Хеш-набор предназначен для эффективного определения того, содержит ли он данный элемент. Список, если я правильно помню, выполняет линейный поиск, который (для большого количества элементов) неэффективен.

0 голосов
/ 24 ноября 2010

Операция LINQ Contains сделает это гораздо более кратким (при условии, что usedFileNames - List<string>):

FileInfo[] filePaths = di.GetFiles("*.pdf");
foreach(FileInfo myInfo in filePaths)
{
    if (!usedFileNames.Contains(myInfo.Name))
    {
        PDFReaderChooser chooser = new PDFReaderChooser(myInfo.Name);
        usedFileNames.Add(myInfo.Name);
    }

}
0 голосов
/ 24 ноября 2010

Попробуйте это:

FileInfo[] filePaths = di.GetFiles("*.pdf");
foreach(FileInfo fInfo in filePaths)
{
    if (!usedFileNames.Contains(fInfo.Name))
    {
        PDFReaderChooser chooser = new PDFReaderChooser(fInfo.Name);
        usedFileNames.Add(fInfo.Name);
    }
}

Как я прокомментировал ваш вопрос, код, который вы разместили, не работает, потому что вы должны вставить оператор прерывания, например:

for (int i = 0; i < filePaths.Length; i++)
{
    bool isInList = false;

    foreach (string fileName in usedFileNames)
    {
        if (fileName.Equals(filePaths[i].Name))
            isInList = true;
    }

    if (isInList == false)
    {
        Console.WriteLine("Not in list! #{0}", x);
        usedFileNames.Add(filePaths[i].Name);
    }
}

В любом случае, я рекомендую вам использовать одну из техник, показанных в ответах на этот вопрос.

...