2011-03-10 3 views
3

최상위 디렉터리에서 특정 정규식과 일치하는 폴더 목록을 가져 오는 가장 효율적인 방법은 무엇입니까? 현재 재귀 적으로 하위 폴더를 반복하여 정규식과 일치하는지 확인한 다음 디렉토리 경로를 사용하여 파일 이름을 가져옵니다.C 정규식을 사용하여 샤프 폴더 검색

현재이 디렉토리에있는 폴더의 양 때문에 현재 검색 방법을 사용하면 약 50 분이 걸립니다.

private void ProcessFiles(string path, string searchPattern) 
{ 
    string pattern = @"^(\\\\server\\folder1\\subfolder\\(MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3}))))$"; 
    DirectoryInfo di = new DirectoryInfo(path); 
    try 
    { 
     Debug.WriteLine("I'm in " + di.FullName); 
     if (di.Exists) 
     { 
      DirectoryInfo[] dirs = di.GetDirectories("*", SearchOption.TopDirectoryOnly); 
      foreach (DirectoryInfo d in dirs) 
      { 
       string[] splitPath = d.FullName.Split('\\'); 


       var dirMatch = new Regex(pattern, RegexOptions.IgnoreCase); 

       if (dirMatch.IsMatch(d.FullName)) 
       { 
        Debug.WriteLine("---Processing Directory: " + d.FullName + " ---"); 
        FileInfo[] files = d.GetFiles(searchPattern, SearchOption.TopDirectoryOnly); 
        AddColor(files, splitPath); 
       } 
       ProcessFiles(d.FullName, searchPattern); 
      } 
     } 


    } 
    catch (Exception e) 
    { 

    } 

} 
+0

50 분은 잘못된 것을 의미합니다. 코드를 게시하십시오. – Jon

+0

또는 : 50 분은 그가 디렉토리를 많이 가지고 있다는 것을 의미합니다. 또는 포함 된 디렉토리는 매핑 된 UNC 경로 나 USB 스틱, DVD 드라이브 등과 같은 느린 장치에 있습니다. – Abel

+1

@Abel : 그 중 UNC 시나리오는 그럴듯한 기회. 그러나 어떤 경우이든, 코드를 살펴 보는 것이이 "디버깅"을위한 합리적인 첫 단계입니다. – Jon

답변

7

은 내가 BCL을하자, 다음, 재귀 필요없이 같은 것을 사용하는 것이 않는 당신을 위해 : 여전히 50 분 실행하는 경우

// I didn't recount the parenetheses... 
Regex re = new Regex("MENS|WOMENS|MENS\sDROPBOX|WOMENS\sDROPBOX)\\((((COLOR\sCHIPS)|(ALL\sMENS\sCOLORS)))|((\d{4})\\(\w+)\\(FINAL\sART|FINAL\sARTWORK)\\(\d{3})))"); 
var dirs = from dir in 
      Directory.EnumerateDirectories(dirPath, "dv_*", 
      SearchOption.AllDirectories) 
      where re.IsMatch(dir) 
      select dir; 

, 당신은 속도가 느린 드라이브에 바로있어, 네트워크 또는 유사합니다.

편집 : 질문이 편집되었습니다. UNC 경로에서 코드를 실행하고 있음을 분명히 보여줍니다. 이것은 속도가 매우 느리고, 속도가 필요하다면 서버 자체에서 실행하십시오.

참고 : GetDirectories (사용하는 경우)과 EnumerateDirectories의 동작 간에는 큰 차이가 있습니다. 마이크로 소프트의 문서 says this about it :

EnumerateDirectories 및 GetDirectories의 방법으로 차이는 다음과 같습니다 당신이 EnumerateDirectories을 사용하면 전체 컬렉션을 반환하기 전에, 당신은 이름의 컬렉션을 열거 시작할 수 있습니다; GetDirectories를 사용할 때 배열에 액세스하기 전에 전체 배열 이름이 반환 될 때까지 기다려야합니다. 따라서 많은 파일과 디렉터리로 작업 할 때 EnumerateDirectories가 더 효율적일 수 있습니다. 질문에 관해서

: 그것은 (예외를 올릴 것이다) 당신이 액세스 할 수없는 디렉토리에서 시작하지 않는,이 액세스 할 수있는 모든 디렉토리를 통해 이동합니다.

+0

귀하의 접근 방식은 내가 액세스 할 수없는 디렉토리를 어떻게 처리합니까? 보안 예외가 발생하거나 해당 디렉토리를 건너 뛸 것인가? 특정 하위 디렉토리에 대한 액세스 권한이없는 경우 열거 형을 중단하지 않으려합니다. – Jesse

+0

@ Jess : 내 업데이트 참조. – Abel

+0

굉장합니다. 나는 그것을 발사하고 무슨 일이 일어날지를 볼 것이다. – Jesse

0

디렉토리 트리에서 가장 빠른 결과를 얻으려면 가장 좋은 방법은 interop을 사용하는 것입니다. FindFirstFile, FindNextFile, FindClose는 친구입니다.

http://msdn.microsoft.com/en-us/library/aa364418%28v=vs.85%29.aspx

하지만 통과하는 거대한 트리가있는 경우 빛의 속도를 기대하지 않습니다.

+0

트래버스 할 매우 큰 트리입니다. 입력 해 주셔서 감사합니다. – Jesse

0

시스템에있는 모든 병렬 기능을 활용하기 위해 하위 폴더에 추가 스레드를 재귀 적으로 시작할 수 있지만 대부분의 오버 헤드는 디스크 액세스 일 가능성이 있습니다.

관련 문제