FileSystemWatcher를 사용하여 디렉토리 모니터링


101

Windows Forms 응용 프로그램을 사용하여 디렉터리를 모니터링하고 여기에 놓인 파일을 다른 디렉터리로 이동하고 있습니다.

현재 파일을 다른 디렉토리로 복사하지만 다른 파일이 추가되면 오류 메시지없이 종료됩니다. 때로는 세 번째 파일로 끝나기 전에 두 개의 파일을 복사합니다.

콘솔 앱이 아닌 Windows Form 애플리케이션을 사용하고 있기 때문입니까? 프로그램 종료를 중지하고 디렉토리를 계속 감시 할 수있는 방법이 있습니까?

private void watch()
{
  this.watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += OnChanged;
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

public void Dispose()
{
  // avoiding resource leak
  watcher.Changed -= OnChanged;
  this.watcher.Dispose();
}

답변:


144

문제는 알림 필터였습니다. 프로그램이 여전히 복사중인 파일을 열려고했습니다. LastWrite를 제외한 모든 알림 필터를 제거했습니다.

private void watch()
{
  FileSystemWatcher watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastWrite;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

6
안녕하세요, 저는이 방법을 사용하고 있었지만 파일을 복사하면 이벤트가 두 번 발생합니다. 한 번은 파일이 비어있을 때 (복사 시작), 한 번은 복사가 완료 될 때 발생합니다. 이 중복 된 이벤트를 피하는 방법은 사용자 지정 제어없이 모든 필터가 처리 할 수 ​​있습니까?
dhalfageme

@dhalfageme 내 응용 프로그램에 의미있는 것이 폴더에 나타나는지 두 이벤트를 모두 확인합니다.
Eftekhari

30

당신은 파일 처리 코드를 제공하지 않았지만, 나는 당신이 그런 일을 처음 작성할 때 모든 사람들이 똑같은 실수를했다고 가정합니다. filewatcher 이벤트는 파일이 생성되는 즉시 발생합니다. 그러나 파일이 완료되는 데 약간의 시간이 걸립니다. 예를 들어 1GB의 파일 크기를 사용하십시오. 파일은 다른 프로그램 (Explorer.exe에서 복사)에 의해 생성 될 수 있지만 해당 프로세스를 완료하는 데 몇 분 정도 걸립니다. 이벤트는 생성시 발생하며 파일을 복사 할 준비가 될 때까지 기다려야합니다.

루프 에서이 함수를 사용하여 파일이 준비 될 때까지 기다릴 수 있습니다 .


25

그 이유는 watcher가 메서드에 대한 지역 변수로 선언되고 메서드가 완료되면 가비지 수집되기 때문일 수 있습니다. 클래스 멤버로 선언해야합니다. 다음을 시도하십시오.

FileSystemWatcher watcher;

private void watch()
{
  watcher = new FileSystemWatcher();
  watcher.Path = path;
  watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                         | NotifyFilters.FileName | NotifyFilters.DirectoryName;
  watcher.Filter = "*.*";
  watcher.Changed += new FileSystemEventHandler(OnChanged);
  watcher.EnableRaisingEvents = true;
}

private void OnChanged(object source, FileSystemEventArgs e)
{
  //Copies file to another directory.
}

18
watcher변수는 Changed 이벤트에 가입했기 때문에 가비지 수집되지 않고 살아 있습니다.
adospace

1
EnableRaisingEvents가로 설정되어 있기 때문이라고 생각합니다 true. 멤버 이벤트 처리기의 상태가 가비지 수집과 관련이 없다고 생각합니다. 저는 EnableRaisingEvents가이 경우에 특별한 동작을 가지고 있다고 생각합니다.
Matias Grioni
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.