2011-08-05 3 views
1
을 모니터링

가능한 중복 :
Detecting moved files using FileSystemWatcher은 FileSystemWatcher는 이동 된 파일

난은 FileSystemWatcher로 이동 된 파일을 모니터하기 위해 노력하고, 여기에 방법에 대한 도움 가지고있어 :

Using FileSystemWatcher with multiple files

그러나 나는 abl 이어야만한다는 것을 알았습니다. e Deleted 및 Created 이벤트를 사용하여 파일이 이동 된 위치의 경로와 이동 된 위치의 경로를 가져옵니다. 그러나 Delete 이벤트에 대해 비슷한 코드를 추가하면 하나 또는 다른 이벤트 만 트리거 할 수 있습니다. 그리고 그것은 어떤 이벤트가 실행될지를 결정하는 이벤트를 연결하는 순서와 같은 것으로 보입니다. 따라서 Created 이벤트를 배선 코드에 마지막으로 넣으면 실행됩니다. 그 반대의 경우에도 삭제 배선을 마지막에 실행하면 실행되지만 생성되지는 않습니다. 여기

코드입니다 :
public class FileListEventArgs : EventArgs 
{ 
    public List<string> FileList { get; set; } 
} 

public class Monitor 
{ 
    private List<string> filePaths; 
    private List<string> deletedFilePaths; 
    private ReaderWriterLockSlim rwlock; 
    private Timer processTimer; 
    private Timer deletionTimer; 
    public event EventHandler FileListCreated; 
    public event EventHandler FileListDeleted; 


    public void OnFileListCreated(FileListEventArgs e) 
    { 
     if (FileListCreated != null) 
      FileListCreated(this, e); 
    } 

    public void OnFileListDeleted(FileListEventArgs e) 
    { 
     if (FileListDeleted != null) 
      FileListDeleted(this, e); 
    } 

    public Monitor(string path) 
    { 
     filePaths = new List<string>(); 
     deletedFilePaths = new List<string>(); 

     rwlock = new ReaderWriterLockSlim(); 

     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Filter = "*.*"; 
     watcher.Deleted += new FileSystemEventHandler(watcher_Deleted); 
     watcher.Created += watcher_FileCreated; 


     watcher.Path = path; 
     watcher.IncludeSubdirectories = true; 
     watcher.EnableRaisingEvents = true; 
    } 


    private void ProcessQueue() 
    { 
     try 
     { 
      Console.WriteLine("Processing queue, " + filePaths.Count + " files created:"); 
      rwlock.EnterReadLock(); 

     } 
     finally 
     { 
      if (processTimer != null) 
      { 
       processTimer.Stop(); 
       processTimer.Dispose(); 
       processTimer = null; 
       OnFileListCreated(new FileListEventArgs { FileList = filePaths }); 
       filePaths.Clear(); 
      } 
      rwlock.ExitReadLock(); 
     } 
    } 

    private void ProcessDeletionQueue() 
    { 
     try 
     { 
      Console.WriteLine("Processing queue, " + deletedFilePaths.Count + " files created:"); 
      rwlock.EnterReadLock(); 

     } 
     finally 
     { 
      if (processTimer != null) 
      { 
       processTimer.Stop(); 
       processTimer.Dispose(); 
       processTimer = null; 
       OnFileListDeleted(new FileListEventArgs { FileList = deletedFilePaths }); 

       deletedFilePaths.Clear(); 
      } 
      rwlock.ExitReadLock(); 
     } 
    } 

    void watcher_FileCreated(object sender, FileSystemEventArgs e) 
    { 
     try 
     { 
      rwlock.EnterWriteLock(); 
      filePaths.Add(e.FullPath); 

      if (processTimer == null) 
      { 
       // First file, start timer. 
       processTimer = new Timer(2000); 
       processTimer.Elapsed += (o, ee) => ProcessQueue(); 
       processTimer.Start(); 
      } 
      else 
      { 
       // Subsequent file, reset timer. 
       processTimer.Stop(); 
       processTimer.Start(); 
      } 

     } 
     finally 
     { 
      rwlock.ExitWriteLock(); 
     } 
    } 

    void watcher_Deleted(object sender, FileSystemEventArgs e) 
    { 
     try 
     { 
      rwlock.EnterWriteLock(); 
      deletedFilePaths.Add(e.FullPath); 

      if (deletionTimer == null) 
      { 
       // First file, start timer. 
       deletionTimer = new Timer(2000); 
       deletionTimer.Elapsed += (o, ee) => ProcessDeletionQueue(); 
       deletionTimer.Start(); 
      } 
      else 
      { 
       // Subsequent file, reset timer. 
       deletionTimer.Stop(); 
       deletionTimer.Start(); 
      } 

     } 
     finally 
     { 
      rwlock.ExitWriteLock(); 
     } 
    } 

그래서 어떻게이 파일이 있던 원래 경로뿐만 아니라 그들이 이동 한 곳으로 새 경로를 얻을해야합니까? (모든 파일이 다중 파일 이동으로 이동 될 때까지 이벤트 처리를 보류하기 위해 타이머 코드가있는 이유에 대한 첫 번째 질문을 참조하십시오.

+0

나는 그렇게 생각하지 않는다. 해당 게시물에서와 같이 파일 이름을 사용하여 파일을 비교하는 데 아무런 문제가 없습니다. 문제는 내가 삭제 및 트리거 이벤트를 만들 수 없다는 것입니다. 적어도 내가 보는 것은 create 이벤트가 트리거되고 삭제가 아직 완료되지 않았다는 것입니다. 필자의 메인 클래스에서는 생성 된 파일 목록을 가져와 삭제 된 파일 목록과 비교할 필요가 있지만 삭제 된 파일 목록은 비어 있으며 생성 된 파일 목록은 채워져 있어야합니다. – Anders

답변

1

두 개의 타이머를 선언하지만 그 중 하나만 사용합니다 (프로세스 삭제 대기열 방법에서 동일한 타이머를 사용합니다). 그래서 간단한 복사/붙여 넣기 실수로 시작합니다.

+0

고마워, 그건 그걸 작동시키려는 시도 였어.하지만 말했듯이, 복사하고 붙여 넣기로 물건을 바꾸는 걸 놓쳤다. 그 실수를 고치는 데는 도움이되지 않았지만, 다시 한번 살펴 보았습니다. 그리고 동일한 ProcessQueue 메소드에서 두 이벤트를 트리거하면 작동 했으므로 그 점을 인정할 것입니다. – Anders

0

필자는 FileSystemWatcher 이벤트가 대기열에 들어 있지 않음을 알아 냈습니다 (주의 : 약 8 년 전).

파일을 처리하는 중 처리 중에 새로운 파일 3 개가 생성되면 3 개의 이벤트가 발생하지 않습니다.

파일을 처리 한 후 디렉토리에서 수동으로 다른 변경 사항을 확인해야 할 수 있습니다.

+0

글쎄, 난 3 파일 이동에 대한 3 이벤트를 얻을 ...하지만 문제는 내가 둘 다 삭제 및 생성 이벤트를 하나만 또는 다른 트리거를 얻을 수 없습니다. – Anders

+0

방금 ​​하나의 디렉토리를 모니터링하고 있습니까? 파일을 이동하면 동일한 디렉토리에 남아있을 수 없습니다. 파일을 이동하면 삭제 된 이벤트가 표시됩니다. 파일이 옮겨지면 생성 된 이벤트를 얻습니다. 어떻게 둘 다 얻을 수 있는지 모르겠습니다. –