2011-08-02 3 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

@Chris - 투표에 사람들을 괴롭히지 마십시오 ... –

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 연산하여 프로그램을 더욱 간결하게 만들 수 있습니다.

관련 문제