2011-12-17 14 views
2

ファイルに重複を検出するアプリケーションを作成しています。私は以下のようにファイルを検索する場合:拒否された:ファイルの取得中にUnauthorizedAccessExceptionが発生する

try 
{ 
    string[] allFiles = Directory.GetFiles(
     directoryPath, "*.*", SearchOption.AllDirectories 
    ); 

    for (int i = 0; i < allFiles.Length; i++) 
    { 
     //decisions 
    } 
} 

catch (UnauthorizedAccessException ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

それは

のアクセスパスに '\ $ Recycle.Bin ....... C' は言います。

フォルダがアクセスできない場合は、次へ移動しますが、プログラムの実行はDirectory.GetFilesメソッドで停止します。ここで

+0

これは機能であり、バグではありません。まともなユーザーは、zombie for * minutes *を実行するプログラムをインストールし、c:\ドライブ上のすべてのファイルを列挙しません。テラバイトは大きな数字です。 –

+0

@Hansは、コード実行時にUIを実行していると言っていますか? – sq33G

答えて

4

が動作するクラスです:

public static class FileDirectorySearcher 
{ 
    public static IEnumerable<string> Search(string searchPath, string searchPattern) 
    { 
     IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern); 

     foreach (string file in files) 
     { 
      yield return file; 
     } 

     IEnumerable<string> directories = GetDirectories(searchPath); 

     foreach (string directory in directories) 
     { 
      files = Search(directory, searchPattern); 

      foreach (string file in files) 
      { 
       yield return file; 
      } 
     } 
    } 

    private static IEnumerable<string> GetDirectories(string directory) 
    { 
     IEnumerable<string> subDirectories = null; 
     try 
     { 
      subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly); 
     } 
     catch (UnauthorizedAccessException) 
     { 
     } 

     if (subDirectories != null) 
     { 
      foreach (string subDirectory in subDirectories) 
      { 
       yield return subDirectory; 
      } 
     } 
    } 

    private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern) 
    { 
     IEnumerable<string> files = null; 
     try 
     { 
      files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly); 
     } 
     catch (UnauthorizedAccessException) 
     { 
     } 

     if (files != null) 
     { 
      foreach (string file in files) 
      { 
       yield return file; 
      } 
     } 
    } 
} 

あなたはこのような使用をすることができます:10キロバイトの下

IEnumerable<string> filesOrDirectories = FileDirectorySearcher.Search(@"C:\", "*.txt"); 

foreach (string fileOrDirectory in filesOrDirectories) 
{ 
    // Do something here. 
} 

(それは再帰的だが、歩留まりの使用はそれを低メモリフットプリントを提供します私のテストで)。パターンではなくディレクトリーではないファイルだけが必要な場合は、EnumerateFileSystemEntriesEnumerateFilesに置き換えてください。

+0

そのコードには大きなバグがあります.EnumerateDirectoriesはIEnumerableを返し、IEnumerableを反復処理するとUnauthorizedAccessExceptionが発生します。上記のコードを更新しました。 –

+0

こんにちは@BlakeNiemyjski、私はコードを見てきましたが、あなたの編集アドレスを言った問題を再現することができませんでした。それを再現するための具体的な手順を教えてください。 – JamieSee

+0

あなたのコードは、ごみ箱のようなシステムフォルダを選択していました。私はあなたのコードを管理者として実行して、あなたのWindowsドライブを指すようにします。 –

関連する問題