2011-08-02 62 views
1

大家好,我已經得到了以下代碼,當某些條件匹配時,它將關閉並獲取路徑目錄中的所有文件,包括子目錄。目前我有兩種方法;一個去獲取所有文件並將它們添加到列表,然後再返回列表的另一種方法。只是想知道這是做這件事的最好方法還是將兩者結合起來更有效率?或者我的代碼可以重寫成更高效?對不起,我對這一切都很陌生!通過多個文件夾返回文件列表的最有效方法

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

@克里斯 - 不要纏着人投票... –

5

你不需要遞歸。

string[] filePaths = Directory.GetFiles(@"c:\SomeDir\", "*.ext", SearchOption.AllDirectories); 
0

如果這是關於獲取文件列表,請看Paul Alan Taylor的回答。

如果您想了解一些關於遞歸的知識:直接從ProcessDir方法返回文件列表。

使用您提供的代碼,至少需要調用,並使其容易出錯。特別是如果該類被重用。

我已經改變了一些東西在你的代碼:

  1. fileInfoList在裏面ProcessDir
  2. 聲明的遞歸調用將結果以「當前」的結果。

    公共類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運算&&它更簡潔的標準一起。

相關問題