前段时间因工作需要做了个小工具,里面涉及到要Monitor一个文件夹,当有新文件产生的时候,就去分析它。还好,Microsoft的.net framework 提供了一个FileSystemWatcher 类,使用 FileSystemWatcher 监视指定目录中的更改。可监视指定目录中的文件或子目录的更改。可以创建一个组件来监视本地计算机、网络驱动器或远程计算机上的文件。
它提供OnChanged 和OnRenamed事件处理程序方法:Ref:http://msdn.microsoft.com/zh-cn/library/system.io.filesystemwatcher.aspx
事件处理程序 | 已处理的事件 | 执行 |
报告文件属性的更改、创建的文件和删除的文件。 | ||
列出重命名的文件和文件夹的新旧路径,需要时可以递归扩展。 |
Code Simple:
private void OnlineMonitorCabBtn_Click(object sender, EventArgs e)
{
String.monitorCabPath=@”C:/CabPath”;
if (!Directory.Exists(monitorCabPath))
{
Directory.CreateDirectory(monitorCabPath);
}
cabWatcher = new FileSystemWatcher(monitorCabPath);
cabWatcher.Created += new FileSystemEventHandler(CabWatcher);
cabWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.Size;
cabWatcher.Filter = "*.cab";
cabWatcher.EnableRaisingEvents = true;
threadStatus = true;
CabQueue.cabQuery.Clear();
onlineCabThread = new Thread(new ThreadStart(new CabOperationDelegate(OnlineCabOperation)));
onlineCabThread.Start();
}
因为要处理Monitor folder中所产生的cab文件,如果一次产生多个cab文件,但是前一个还没有处理完,怎么办呢?所以这里要用到Queue,当一有文件产生就放到Queue里面去,我处理就直接到Queue里面去拿cab。
private void CabWatcher(object sender, FileSystemEventArgs e)
{
CabQueue.cabQuery.Enqueue(e.FullPath);
}
CabQueue class:
public static class CabQueue
{
public static Queue<string> cabQuery = new Queue<string>();
public static object qLock = new object();
public static List<string> GetCab()
{
lock (qLock)
{
List<string> cabFiles = new List<string>();
for (int i = 0; i < cabQuery.Count; i++)
{
cabFiles.Add(cabQuery.Dequeue().ToString());
}
return cabFiles;
}
}
}
这里为什么要和Lock呢? 因为我还有另一个Event去Monitor 这个Queue, 如果它不为空,那么我就取里面的list出来进行处理,如果当我取Queue里面的数据的时候,外面又有文件往里面写,它就会产生Exception,所以我用把这个Queue给lock住,当它完后再其它线程才能往里面写数据。Lock确保当一个纯种位于代码的临界区,另一个线程不进入临界区。如果其它线程试图进入锁定的代码,则它将一直等待,直到该对象释放。Ref: http://msdn.microsoft.com/zh-cn/library/c5kehkcz(VS.80).aspx
public void OnlineCabOperation()
{
while (threadStatus)
{
if (0 != CabQueue.cabQuery.Count)
{
List<string> getCabList = new List<string>();
getCabList = CabQueue.GetCab();
for (int i = 0; i < getCabList.Count; i++)
{
if (GuidGview.InvokeRequired)
{
GuidGview.Invoke(new UpdateUIDelegate(UpdateUI), getCabList[i]);
}
}
}
Thread.Sleep(2000);
}
}