2011-08-02 21 views
1

こんにちはすべて私は、特定の基準が一致すると、サブディレクトリを含むルートディレクトリからすべてのファイルを取得して取得する次のコードを持っています。現在私は2つの方法があります。 1つはすべてのファイルを取得してListに追加し、もう1つはListを返すメソッドです。これを実行する最善の方法であるのか、それとも2つを組み合わせる方が効率的なのか不思議です。あるいは、私のコードをより効率的に書き直すことができますか?申し訳ありません、私はこのすべてに全く新しいです!複数のフォルダにファイルリストを返す最も効率的な方法

public class FileUtility 
    { 
     List<FileInfo> fileInfoList = new List<FileInfo>(); 

     public void ProcessDir(string sourceDir, String userName) 
     { 
      try 
      { 
       string userNameFirstLetter = userName.First().ToString(); 
       DirectoryInfo di = new DirectoryInfo(sourceDir); 

       foreach (FileInfo fi in di.GetFiles()) 
       { 
        if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf") 
        { 
         if (fi.Name.Contains(userName)) 
         { 
          if (fi.Name.Contains("X")) 
          { 
           if(fi.Name.First().ToString().Equals(userNameFirstLetter)) 
           { 
            if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName)) 
            { 
             fileInfoList.Add(fi); 
            } 
           } 
          } 
         } 
        } 
       } 

       // Recurse into subdirectories of this directory. 
       string[] subdirEntries = Directory.GetDirectories(sourceDir); 
       foreach (string subdir in subdirEntries) 
       { 
        // Do not iterate through reparse points 
        if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) 
        { 
         ProcessDir(subdir, userName); 
        } 
       } 
      } 
      catch (DirectoryNotFoundException exp) 
      { 
       throw new DirectoryNotFoundException("Directory not found " + exp.Message); 
      } 
      catch (IOException exp) 
      { 
       throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message); 
      } 
     } 

     public List<FileInfo> GetFileInfoList() 
     { 
      return fileInfoList; 
     } 
} 

答えて

2

あなたはこのような何かを行うことができます。

DirectoryInfo dir = new DirectoryInfo(@"C:\PathName"); 
IEnumerable<FileInfo> files = dir.GetFiles("*.*"); 

は、その後、あなたはこれをダウンフィルタリングするLINQを使用することができますが、C#3.5またはそれを超えると、私はあなたがいると仮定を使用している場合。以下のような何か:

// Only use files with userName in the filename 
files = files.Where(f => f.Name.Contains(userName)); 

または2を組み合わせる:

DirectoryInfo dir = new DirectoryInfo(@"C:\PathName"); 
IEnumerable<FileInfo> files = dir.GetFiles("*.*").Where(f => f.Name.Contains(userName)); 
+0

これははるかに効率的です:)ありがとう! –

+0

@Chris - 投票のために人々を嫌うことはありません... –

5

あなたは再帰を必要としません。

0

ファイルのリストについては、Paul Alan Taylorの答えをご覧ください。

再帰について習得したい場合は、ProcessDirメソッドから直接ファイルのリストを返します。

あなたが提供するコードを使用すると、少なくとも呼び出す必要があり、エラーを起こしやすくなります。特にクラスが再利用されている場合

私はあなたのコード内のいくつかのことを変更しました:fileInfoListがProcessDir

  • 内で宣言され

    1. 再帰呼び出しは、「現在」の結果に結果を追加します。

      パブリッククラスFileUtility {

      public List<FileInfo> ProcessDir(string sourceDir, String userName) 
          { 
           List<FileInfo> fileInfoList = new List<FileInfo>(); 
      
           try 
           { 
            string userNameFirstLetter = userName.First().ToString(); 
            DirectoryInfo di = new DirectoryInfo(sourceDir); 
      
            foreach (FileInfo fi in di.GetFiles()) 
            { 
             if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf") 
             { 
              if (fi.Name.Contains(userName)) 
              { 
               if (fi.Name.Contains("X")) 
               { 
                if(fi.Name.First().ToString().Equals(userNameFirstLetter)) 
                { 
                 if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName)) 
                 { 
                  fileInfoList.Add(fi); 
                 } 
                } 
               } 
              } 
             } 
            } 
      
            // Recurse into subdirectories of this directory. 
            string[] subdirEntries = Directory.GetDirectories(sourceDir); 
            foreach (string subdir in subdirEntries) 
            { 
             // Do not iterate through reparse points 
             if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) 
             { 
              fileInfoList.AddRange(ProcessDir(subdir, userName)); 
             } 
            } 
           } 
           catch (DirectoryNotFoundException exp) 
           { 
            throw new DirectoryNotFoundException("Directory not found " + exp.Message); 
           } 
           catch (IOException exp) 
           { 
            throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message); 
           } 
      
           return fileInfoList; 
          } 
      

      }

    注:コードが "論理と" &&を使用ifステートメントを組み合わせることによって、例えば、改善することができます。

  • 0

    もっと効率的な方法があります。

    string[] filePaths = Directory.GetFiles(rootDirectory,searchPattern,SearchOption.AllDirectories); 
    

    ファイルの選択基準を満たすようにsearchPatternを変更することをお勧めします。

    AFAIK searchPatternは正規表現と同様に動作します。

    またあなたはおそらく、クラスのインスタンスを必要としない、あなたの基準で

    0

    それらをフィルタリングするためにそれらを介して、すべての特定のファイル拡張子に一致するファイルと、ループを得ることができます。このように、代わりにそれは静的なことを検討:

    public static class FileUtility 
        { 
        private static void ProcessDir(string sourceDir, String userName, List<FileInfo> fileInfoList) 
        { 
         try 
         { 
          string userNameFirstLetter = userName.First().ToString(); 
          DirectoryInfo di = new DirectoryInfo(sourceDir); 
    
          foreach (FileInfo fi in di.GetFiles()) 
          { 
           if ((fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf") 
            && fi.Name.Contains(userName) && fi.Name.Contains("X") 
            && fi.Name.First().ToString().Equals(userNameFirstLetter) 
            && fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName)) 
           { 
            fileInfoList.Add(fi); 
           } 
          } 
    
          // Recurse into subdirectories of this directory. 
          string[] subdirEntries = Directory.GetDirectories(sourceDir); 
          foreach (string subdir in subdirEntries) 
          { 
           // Do not iterate through reparse points 
           if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) 
           { 
            ProcessDir(subdir, userName, fileInfoList); 
           } 
          } 
         } 
         catch (DirectoryNotFoundException exp) 
         { 
          throw new DirectoryNotFoundException("Directory not found " + exp.Message); 
         } 
         catch (IOException exp) 
         { 
          throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message); 
         } 
        } 
    
        public static List<FileInfo> GetFileInfoList(string sourceDir, string userName) 
        { 
         List<FileInfo> fileInfoList = new List<FileInfo>(); 
         ProcessDir(sourceDir, userName, fileInfoList); 
         return fileInfoList; 
        } 
        } 
    

    また、あなたが基準一緒&& AND演算することにより、それをより簡潔にすることができます。

    関連する問題