2010-11-24 7 views
2

Mein Programm geht in ein Verzeichnis und sucht nach PDF-Dateien, um sie zu analysieren. Dieses Programm läuft immer, deshalb muss ich sicherstellen, dass die gleiche Datei nicht erneut analysiert wird.Schleife für PDF-Dateien

Ich habe eine Liste verwendet, um die Dateinamen zu speichern und dann zu überprüfen, ob sie da sind.

Mein Code funktioniert nicht in Bezug auf das, wenn jemand einen Blick darauf werfen kann, was falsch ist, würde es sehr geschätzt werden.

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); 
    } 

} 
+0

Ihr Code funktioniert nicht, da Sie nach "isInList = true;" eine break-Anweisung einfügen müssen. –

+0

@ AS-CII: das macht keinen Sinn, da er 'isInList == false' später testet; es bricht effektiv dort ... – Domenic

+0

Ja, aber jedes Mal, wenn die Schleife ausgeführt wird, aktualisiert die isInList Variable auch, wenn ein fileName gefunden wird. Beispiel: # 1 - Gleich, isInList = true; # 2 - NotEqual, isInList = false. In diesem Fall ist der letzte Wert, den die Variable annimmt, falsch und daher ist das Ergebnis völlig falsch. Wenn Sie mir nicht vertrauen, testen Sie den Code selbst :) Ps. Eine Alternative könnte auch sein, die Else-Anweisung zu entfernen. –

Antwort

0

Versuchen Sie folgendes:

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); 
    } 
} 

Wie ich auf Ihre Frage kommentierte der Code, den Sie geschrieben funktioniert nicht, weil Sie eine break-Anweisung einfügen müssen, wie folgt aus:

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); 
    } 
} 

Wie auch immer, ich empfehle Ihnen, eine der in dieser Frage gezeigten Antworten zu verwenden.

+0

Darf ich eine 'foreach' vorschlagen? – Domenic

+0

Nun, ich hatte den Code nicht geändert, weil er vielleicht den Counter benutzen muss. Wie auch immer, ich repariere es. Danke :) –

0

A LINQ Enthält Betrieb so viel prägnanter machen würde (usedFileNames Annahme, daß ein 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); 
    } 

} 
4

prägnant noch:

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); 
} 

Diese abstrahiert schön die Logik weg, die aus Zahlen, die Dateinamen müssen Sie (außerhalb der Schleife) von der Logik verarbeiten, die sie verarbeitet (innerhalb der Schleife).

+0

lol Ich habe gerade dies geschrieben. 2 Sekunden zu langsam, nehme ich an. +1 – Kelly

+0

Haha, die mich über meine eigenen "zwei Sekunden zwei langsam" auf eine andere Frage vor zehn Minuten fühlen lassen: D – Domenic

3

Während die anderen Antworten bessere Lösungen für das Problem sind, erklären sie nicht, warum der ursprüngliche Code nicht funktioniert hat. Das Problem besteht darin, dass der Algorithmus den Wert der Variablen isInList überschreibt, der daher nur für die letzte Datei in der Liste gilt. Dies würde das Problem beheben:

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); 
    } 
} 

Ich möchte hinzufügen, dass es besser ist, eine HashSet statt einer Liste für Ihre usedFileNames Sammlung zu verwenden. Der Hash-Satz soll effizient bestimmen, ob er ein bestimmtes Element enthält. Die Liste, wenn ich mich richtig erinnere, führt eine lineare Suche durch, die (für große Stückzahlen) ineffizient ist.

+0

+1 für eine gute Erklärung des ursprünglichen Problems, und eine spezielle unsichtbare +1 für die Erwähnung von 'HashSet'; das ist nichts, was ich in meinem eigenen Code mache, aber ich sollte !! – Domenic