2011-08-05 35 views
1

可能重複:
Detecting moved files using FileSystemWatcherFileSystemWatcher的監控移動的文件

我試圖監視與FileSystemWatcher對象移動的文件,並得到了來這兒的路上一些幫助:

Using FileSystemWatcher with multiple files

但是,我發現我必須是abl e同時使用Deleted和Created事件,以便獲取文件被移動的路徑以及移動到的位置的路徑。但是當我爲Delete事件添加類似的代碼時,我只能得到一個或另一個事件觸發。它似乎是我確定哪個事件將運行的事件的順序。因此,如果我將最後一次創建的事件放在佈線代碼中,那麼將會運行,反之亦然,如果將最後一次刪除佈線,則會運行,但不會創建。

下面的代碼:

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

我不這麼認爲。我在使用文件名比較文件時沒有問題,就像那篇文章中那樣。問題是我無法同時刪除和創建觸發事件。或者至少我所看到的是創建事件被觸發並且刪除還沒有完成。在我的主類中,我需要創建文件列表並將其與已刪除文件列表進行比較,但已刪除的文件列表爲空,而創建的文件列表已填充。 – Anders

回答

1

您聲明兩個定時器,但您只使用其中一個(在進程刪除隊列方法中使用相同的一個)。所以看起來像是一個簡單的複製/粘貼錯誤。

+0

謝謝,這是我試圖讓它工作,但我錯過了改變一些東西與複製和粘貼,如你所說。雖然它並沒有幫助修復這個錯誤,但它讓我再次審視它,並且我發現如果我在同一個ProcessQueue方法中觸發了這兩個事件,它的確行得通,所以我會相信你。 – Anders

0

我發現FileSystemWatcher事件不排隊(警告:這是大約8年前)。

如果您正在處理一個文件,並且在處理過程中創建了3個新文件,您將不會獲得3個事件。

處理完文件後,您可能需要手動檢查目錄是否存在其他更改。

+0

那麼,我確實得到了3個移動3個文件的事件......但問題是我無法同時觸發刪除和創建事件,只有一個或另一個。 – Anders

+0

你只是在監視一個目錄嗎?如果您移動文件,它不能保持在同一個目錄中。如果文件被移出,您將獲得已刪除的事件。如果文件被移入,您將獲得創建的事件。我不明白你怎麼能得到這兩個。 –