2017-10-22 1 views
1

다중 폴더 디렉토리의 파일을 검색하는 데 Directory.GetFiles()을 사용하고 있으며 일부 폴더가 너무 커서 검색에 최대 60 초가 걸릴 수 있습니다. 아래의 코드에서 사용자가 입력을 중지 한 후 검색이 잠시 시작됩니다.이 유형은 사용자가 파일 이름을 입력하고 입력하는 동안 일시 중지하지 않지만 단어 중간에 일시 중지하면 검색이 시작되고 그/그녀가 다시 타이핑을 시작하더라도 그것이 끝날 때까지 멈추지 말라.Directory.GetFiles 검색을 중지하는 방법이 있습니까

사용자가 입력하는 동안 검색을 중지하려면 inputFileName_TextChanged 메소드를 사용하십시오.

Directory.GetFiles을 사용할 때 이미 시작된 검색을 중지 할 수있는 방법이 있습니까?

using System.Timers; 
using System.IO; 

namespace findFileTest 
{ 

    public partial class MainWindow : Window 
    { 
     Timer timer = new Timer(); 

     public MainWindow() 
     { 
      InitializeComponent(); 

      timer.Elapsed += new ElapsedEventHandler(TimerEvent); 
      timer.Interval = 1000; 
      timer.Enabled = true; 
      timer.Stop(); 
     } 

     private void inputFileName_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      // How to stop the search currently in process here 
      timer.Stop(); 
      timer.Start(); 
     } 

     public void TimerEvent(object source, ElapsedEventArgs e) 
     { 
      timer.Stop(); 
      findFile(); 
     } 

     private void findFile() 
     { 
      string fName = ""; 

      this.Dispatcher.Invoke(() => { 
       fName = inputFileName.Text; 
      }); 

      var fType = ".txt"; 
      var fileName = fName.Trim() + fType; 

      var file = Directory.GetFiles(@"C:\TestFolder\", fileName, SearchOption.AllDirectories).FirstOrDefault(); 
      if (file == null) { 
       Console.WriteLine("File not found"); 
      } 
      else { 
       Console.WriteLine("Found:" + file); 
      } 
     } 
    } 
} 
+6

잘못된 방법으로 Directory.EnumerateFiles()를 중지하는 것은 매우 쉽습니다. foreach 루프에서 벗어나기 만하면됩니다. –

+0

먼저 귀하의 제안에 감사드립니다. 이걸 제대로 이해하면'.FirstOrDefault()'를 제거하고 내 검색 패턴을 * .txt *로 수정해야합니다. 그래서 .txt 확장자를 가진 모든 파일을 얻을 수 있습니다. 그런 다음 결과를 반복하기 위해'foreach '를 사용하십시오. 이것이 올바른 경우, 양쪽 모두가 경로 목록을 리턴하면, 하나는'IEnumerable '을 리턴하고 다른 하나는 다음과 같은 배열을 리턴합니다.'Directory.GetFile()'대신'Directory.EnumerateFiles()'를 사용하면 어떤 이점이 있습니까? 'string []'하지만 결국 양쪽 모두 멈출 수 있다고 생각합니다. 정말 다른 점은 무엇입니까? –

+0

@ Peter Duniho는 이미 내 질문에 감사합니다. –

답변

2

Directory.GetFiles를 사용하는 경우 이미 시작 된 검색을 중지하는 방법이 있나요?

아니요, 안전하지 않습니다. GetFiles() 메서드는 반환하기 전에 작업을 중단하는 메커니즘을 제공하지 않습니다. 스레드를 중단해야 할 경우 다른 문제가 발생할 수 있습니다.

this comment에 언급 된대로 귀하의 요청을 그대로 받아들이면 대답은 Directory.EnumerateFiles() 방법을 대신 사용하는 것입니다. 이 메서드는 한 번에 하나의 파일을 반환하는 열거자를 제공하여 기본 FindFirstFile()FindNextFile()의 의미를 나타냅니다. 새 파일이 반환 될 때마다 더 많은 작업을 수행하지 않고 열거를 중단하고 돌아올 수 있습니다.

EnumerateFiles()을 사용해도 검색 패턴과 일치하는 것을 찾을 때까지 첫 번째 파일 결과가 표시되지 않습니다. EnumerateFiles()을 사용하도록 전환하면 EnumerateFiles()을 사용하는 대신 입력에 고유 한 일치 작업을 수행하는 것이 좋습니다. 나는. 검색 문자열로 "*"을 전달하십시오. 이렇게하면 전반적인 작동이 조금 느려지지만 일치하는 파일이 발견되었을 때만이 아니라 의 검색 디렉토리와 하위 디렉토리에있는 모든 파일에 대한 작업을 방해 할 수 있습니다.

마지막으로 명확한 유스 케이스가 있다면 Directory 클래스를 사용하여 다시 생각해 볼 수 있습니다. 게시 한 코드에 따라 파일 시스템 검색을 시작합니다. 사용자가 새로운 텍스트를 입력 할 때마다 반드시 느린 작업입니다. IMHO를 사용하면 색인을 한 번 구축하는 것이 좋습니다 (예 : —이없는 파일 이름을 Path.GetFileNameWithoutExtension() —으로 매핑하는 Dictionary<string, List<string>>). 일치하는 파일의 전체 경로를 디렉토리에 추가하는 것이 좋습니다. 그렇게하면 아무 것도 방해 할 필요가 없습니다. 사용자가 입력 한 텍스트 뒤의 "검색"부분은 거의 즉각적입니다.

물론 디렉토리가 완전히 색인되기 전에 초기 지연이 있습니다. 어떻게 대처할 지 당신에게 달려 있습니다. 그러나 사용자에게 찾고있는 파일이 이미 색인 된 파일과 일치하는 경우에 대비하여 색인 생성이 완전히 완료되지 않았 음을 사용자에게 알려주는 메커니즘을 제공하는 것이 좋습니다.

주 당신이 StringComparer.OrdinalIgnoreCase하여 사전을 초기화 할 것, 그래서 —은 대소 문자를 구분 등 — FAT, FAT32, NTFS를 사용하는 일반적인 Windows 파일 시스템. "Ordinal". 파일 시스템 이름이 사용자가 입력 한 정확한 문자와 일치해야하고 "대소 문자 무시"가 필요하므로 검색에서 대소 문자를 구분하지 않습니다.

사용자 시나리오를 보면 사용자가 프로그램을 사용하여 검색하는 동안 파일이 추가되거나 제거되지 않을 것 같아요. 그러나 해당 시나리오가 염려되는 경우 사용자에게 "새로 고침"버튼을 제공하여 디렉토리의 색인을 다시 만들거나 FileSystemWatcher을 사용하여 파일을 추가하거나 제거하면 색인을 자동으로 업데이트 할 수 있습니다.

+0

@ Peter Duniho 처음 두 단락에서, 왜 Directory.GetFile() 대신에 Directory.EnumerateFiles()를 사용했는지에 대한 질문에 답했습니다. 색인 생성 방법에 대한 아이디어는 매우 훌륭하게 들리지만 조금 더 복잡한 것처럼 들리지만 분명히 살펴볼 것입니다. 빠른 질문, 인덱싱 된 파일은 일반적으로 어떻게 처리됩니까? 사전 목록을 얻은 다음 저장하면 나중에 참조 할 수 있습니다. –

+2

예. 'List '은 지정된 이름에 대한 모든 파일 이름의 전체 경로 목록입니다. 예 : "foo.txt"라는 파일이있는 세 개의 디렉토리가 있다면 사전에 "foo"키 아래에 세 파일의 전체 경로가있는 목록이 있습니다. 인덱스를 만들 때'TryGetValue()'를 사용하여 키가 이미 존재하는지 확인해야합니다. 그럴 경우, 발견 한 새 파일을 해당 키의 목록에 추가하고 그렇지 않은 경우 먼저 목록을 작성하여 키의 값으로 추가 한 다음 새 파일을 새 목록에 추가하십시오. –

+0

확장 기능이없는 파일 이름이 키가되며 경로는'List'의 값이됩니다. 이제 첫 번째 인덱스가 완료되면 대부분의 요청은 검색이 아닌'List'를 통해 수행 될 것이므로'List '가 얼마나 클 수 있는지에 대한 제한이 있습니까? 감사. –

관련 문제