2010-11-24 8 views
2

私のプログラムは、ディレクトリに入り、それらを解析するためにpdfファイルを検索します。このプログラムは常に実行されているので、同じファイルをもう一度解析しないようにする必要があります。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); 
    } 

} 
+0

"isInList = true;"の後ろにbreakステートメントを挿入する必要があるため、コードが機能しません。 –

+0

@ AS-CII:彼は 'isInList == false'を後でテストするので意味がありません。それは事実上そこに壊れています... – Domenic

+0

はい、ループが実行されるたびにisInList変数が更新され、fileNameが見つかると更新されます。例:#1 - 等しい、isInList =真; #2 - NotEqual、isInList = false。この場合、変数が前提とする最後の値はfalseであるため、結果は完全に間違っています。あなたが私を信頼しない場合は、コードを自分でテストしてください:) P.s.別の方法として、else文を削除することもできます。 –

答えて

0

このお試しください:

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); 
    } 
} 
:私はあなたの質問にコメントとして、あなたは、break文を挿入する必要があるため、あなたが投稿したコードは次のように、動作しません

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

とにかく、この質問回答に示されているテクニックの1つを使用することをお勧めします。

+0

「foreach」を提案してもよろしいですか? – Domenic

+0

まあ、私はコードを変更していない可能性がありますので、彼はカウンターを使用する必要があります。とにかく私はそれを修正する。ありがとう:) –

0

LINQ操作は、このはるかに簡潔な(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); 
    } 

} 
4

より簡潔:

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

これはうまく割り出しロジックを抽象化処理する必要があるファイル名(ループ外)、処理するロジック(ループ内)からのファイル名です。

+0

笑私はこれを書いていた。 2秒遅すぎると思う。 +1 – Kelly

+0

10分前の別の質問で自分の「2秒遅い」について気分が良くなるのは母:D – Domenic

3

他の回答は問題の解決策としてはより優れていますが、元のコードが機能しなかった理由は説明していません。問題は、アルゴリズムが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); 
    } 
} 

usedFileNamesコレクションのListの代わりにHashSetを使用する方がよいと付け加えます。ハッシュセットは、それが所与のアイテムを含むかどうかを効率的に決定するように設計されている。このリストは、正しくリコールすると線形検索を行いますが、これは(多数の項目に対して)非効率的です。

+0

元の問題の説明のためには+1、 'HashSet'には特別な目に見えない+1があります。それは自分のコードで行うことではありませんが、私はすべきです! – Domenic