前沿:前不久在逛網(wǎng)的時候下到一個SyncPlicity軟件,是一種支持多文件夾的免費網(wǎng)絡同步工具。簡單的說就是安裝此軟件后您可以指定一個或多個監(jiān)視目錄,當這些目錄中的文件發(fā)生改變后(重命名,刪除,移動,創(chuàng)建)他會將改動的內容傳給遠端服務器。這樣你在異地只要安裝了這個軟件,便可以從遠端服務器上同步到這些變動的文件,同時異地上的任何操作又將同樣的傳遞到本地。
于是來了興趣,打算模擬一下如何去監(jiān)視指定的目錄的變動。
1、通過Timer來間隔檢測文件夾中的變動,主要是對最后時間進行判斷。
2、能否基于系統(tǒng)提供的Api或類庫來實現(xiàn)監(jiān)視?
顯然,對于第一種方案是很不科學,也很不好把控的。如果用timer那么將會占用過多的資源,同時對于變動不能很明確的定位,在過深層級下的文件變動通過這種方式將很難遍歷到,即便能夠遍歷到則其中的遍歷也會增加系統(tǒng)的復雜度。然而在Net提供的類中有一個System.IO.FileSystemWatcher 通過命名就可以看出其功效——監(jiān)視者。于是按照自己的思路進行Demo的編寫。
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6namespace FileWatch
7{
8 class Program
9 {
10 static void Main(string[] args)
11 {
12 //用于輸入需要監(jiān)聽的路徑 例如 c:\
13 string s = Console.ReadLine();
14 new FileWatchClass(s);
15 Console.ReadKey();
16 }
17 }
18
19 class FileWatchClass
20 {
21 System.IO.FileSystemWatcher FileWatcher = new FileSystemWatcher ();
22 public FileWatchClass(string WatcherPath)
23 {
24 FileWatcher.Filter = "*.*"; //設定監(jiān)聽的文件類型
25 FileWatcher.Path = WatcherPath; //設定監(jiān)聽的目錄
26 FileWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed); //Changed 事件處理
27 FileWatcher.Renamed += new RenamedEventHandler(FileWatcher_Renamed);//Renamed事件處理
28 FileWatcher.Created += new FileSystemEventHandler(FileWatcher_Created);//Created事件處理
29 FileWatcher.Deleted += new FileSystemEventHandler(FileWatcher_Deleted);//Deleted事件處理
30 FileWatcher.IncludeSubdirectories = true;//設置監(jiān)聽子目錄
31 FileWatcher.EnableRaisingEvents = true;//開始進行監(jiān)聽(其實此處是標示是否進行事件監(jiān)聽和拋出)
32 }
33
34 void FileWatcher_Deleted(object sender, FileSystemEventArgs e)
35 {
36 Console.WriteLine("【"+e.ChangeType+"】"+e.FullPath+" 刪除 ");
37 }
38
39 void FileWatcher_Created(object sender, FileSystemEventArgs e)
40 {
41 Console.WriteLine("【" + e.ChangeType + "】" + e.FullPath + " 被創(chuàng)建 ");
42 }
43
44 void FileWatcher_Renamed(object sender, RenamedEventArgs e)
45 {
46 Console.WriteLine("【" + e.ChangeType + "】" + e.OldFullPath + " 由原來名 " + e.OldName + " 改名為 " + e.Name);
47 }
48
49 void FileWatcher_Changed(object sender, FileSystemEventArgs e)
50 {
51 Console.WriteLine("【" + e.ChangeType + "】" + e.FullPath + " 發(fā)生改變 ");
52 }
53 }
54}
編譯這個Demo,我們來進行測試一下。原來本打算只是實現(xiàn)功能,當測試時突然發(fā)現(xiàn)了系統(tǒng)在處理文件時的一些小信息:
1、同級目錄內復制文件(Test.txt) 結果為(捕獲到 一次創(chuàng)建,兩次改變):
【Created】c:\復制Test.txt 被創(chuàng)建
【Changed】c:\復制Test.txt 發(fā)生改變
【Changed】c:\復制Test.txt 發(fā)生改變
2、非同級目錄復制(Test.txt 復制到 Test文件夾下面) 結果為(捕獲到 一次創(chuàng)建,兩次改變+一次文件夾改變):
【Created】c:\Test\Test.txt 被創(chuàng)建
【Changed】c:\Test\Test.txt 發(fā)生改變
【Changed】c:\Test\Test.txt 發(fā)生改變
【Changed】c:\Test 發(fā)生改變
3、非同級的剪切 粘貼(Test.txt 剪切到 Test 文件夾下)結果為(捕獲到 一次刪除 一次創(chuàng)建 一次文件夾改變):
【Deleted】c:\Test.txt 刪除
【Created】c:\Test\Test.txt 被創(chuàng)建
【Changed】c:\Test 發(fā)生改變
可以看出一個小問題,對于未建立的文件,在創(chuàng)建時在創(chuàng)建后會出現(xiàn)兩次Changed,然而對于已經(jīng)存在的文件移動在另一個目的地時沒有那“多余”的兩次Changed 這是為什么呢??
該文章在 2023/12/26 22:51:53 編輯過