用FileSystemWatcher实现山寨版Second Copy [1]

Second Copy®是一个强大的自动备份工具,我曾用他来做文件同步和网页防篡改,支持ftp、email通知、定时等,功能非常不错。

C#中正好也提供了一个有监视功能的FileSystemWatcher,我们用他来监视本地文件或子目录的变化,然后将变化的文件即时反馈到你的目标存储即可,我给这个小玩意取了一个名字,叫BakCopy,下面简单说下思路

1、建立BakCopy任务,任务属性包括名称、源目录、目标目录、监视文件类型、是否监视子目录,

将任务属性保存在config.ini文件中,格式如下,一个ini文件中可以保存多个任务。autostart表示是否在启动程序时自动启动监视任务。

2、在显示主界面时,读取ini文件,显示所有任务,显示所有任务的状态。autostart=1的任务自动启动,并在窗口下方显示log。

3、右击任务时显示popmenu,可以启动、停止、修改任务。

4、启动任务时,采用多线程调用监视类FileCopyThread。

5、FileCopyThread中监视到有create、delte、rename、change等时间时,进行相应的copyfile操作,并在log里显示。

------------------------------------------------------------

FileCopyThread类:

1 using System;
2  using System.Collections.Generic;
3  using System.Text;
4  using System.IO;
5  using System.Security.Permissions;
6
7  namespace BakCopy
8 {
9 class FileCopyThread
10 {
11 private FileSystemWatcher fsw;
12 private string srcDir = "";
13 private string dstDir = "";
14 private string fileType = "*.*";
15 private bool includeSubdir = false;
16
17 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
18 public FileCopyThread(string srcDir, string dstDir, string fileType, bool includeSubdir)
19 {
20 this.srcDir = srcDir;
21 this.dstDir = dstDir;
22 this.fileType = fileType;
23 this.includeSubdir = includeSubdir;
24
25 this.fsw = new FileSystemWatcher();
26 this.fsw.Path = this.srcDir;
27 this.fsw.Filter = this.fileType;
28 this.fsw.EnableRaisingEvents = false;
29 this.fsw.IncludeSubdirectories = this.includeSubdir;
30 }
31
32 public void run()
33 {
34 this.fsw.Changed += new FileSystemEventHandler(this.fsw_Changed);
35 this.fsw.Created += new FileSystemEventHandler(this.fsw_Created);
36 this.fsw.Deleted += new FileSystemEventHandler(this.fsw_Deleted);
37 this.fsw.Renamed += new RenamedEventHandler(this.fsw_Renamed);
38 this.fsw.EnableRaisingEvents = true;
39 Console.WriteLine("FileCopyThread.run={0} HashCode={1}", System.Threading.Thread.CurrentThread.Name, this.GetHashCode());
40 }
41
42 private void fsw_Changed(object sender, FileSystemEventArgs e)
43 {
44 Console.WriteLine("Change File: " + e.FullPath + " " + e.ChangeType);
45 //TODO copy file here
46   }
47
48 private void fsw_Created(object sender, FileSystemEventArgs e)
49 {
50 this.fsw_Changed(sender, e);
51 //TODO copy file here
52   }
53
54 private void fsw_Deleted(object sender, FileSystemEventArgs e)
55 {
56 Console.WriteLine("Delete File: " + e.FullPath + " " + e.ChangeType);
57 //TODO delete file here
58   }
59
60 private void fsw_Renamed(object sender, RenamedEventArgs e)
61 {
62 Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
63 //TODO rename file here
64  
65 }
66
67 ~FileCopyThread()
68 {
69 this.fsw.EnableRaisingEvents = false;
70 Console.WriteLine("~FileCopyThread={0} HashCode={1}", System.Threading.Thread.CurrentThread.Name, this.GetHashCode());
71 }
72 }
73 }
74
75  

------------------------------------------------------------

启动任务:

1 // start thread
2  Thread myThread = new Thread(new ThreadStart(new FileCopyThread(srcDir, dstDir, filetype, subdir).run));
3 myThread.IsBackground = true;
4 myThread.Name = taskname;
5 myThread.Start();
6  this.threadNameTable.Add(taskname, myThread);

------------------------------------------------------------

停止任务:

1 //stop it
2  foreach (DictionaryEntry de in this.threadNameTable)
3 {
4 if (de.Key.ToString() == taskname)
5 {
6 //Thread th = (Thread)this.threadNameTable[taskname];
7   Thread th = (Thread)de.Value;
8 th.Join();
9 th.Abort();
10 this.threadNameTable.Remove(taskname);
11 break;
12 }
13 }

------------------------------------------------------------

问题:

启动任务后,调用了FileCopyThread.run,目录监视开始了,见线程对象加到一个列表中。在需要停止任务时,从列表中获取线程,然后将其停止掉。但是Thread.Abort()终止线程后,并没有调用到FileCopyThread的析构函数,也就是任务结束后,目录监视仍然存在。

好像我的这个写法有点问题,大侠指点下。

------------------------------------------------------------

后续工作:

才做了一个壳子,后面得完善copyfile,加入系统托盘,定时器,支持ftp,email通知等,慢慢来吧。

附件:https://files.cnblogs.com/longware/BakCopy.rar

原文地址:https://www.cnblogs.com/longware/p/1773874.html