FileSystemWatcher
转:http://www.cnblogs.com/zhaojingjing/archive/2011/01/21/1941586.html
注意:用FileWatcher的Created监控文件时,是指文件刚创建的时候就触发Created(仅仅是出现文件名时),此时的文件还未完成写操作(比如一个图片文件),文件也不是一个完整的文件。用Image.FromFile加载刚刚监听的文件,会报“内存不足”异常。
下面为简单用法:
using System;
using System.IO; namespace test
{
class Program
{
static void Main(string[] args)
{
WatcherStrat(@"C:\test", "*.txt");
//由于是控制台程序,加个输入避免主线程执行完毕,看不到监控效果
Console.ReadKey();
} private static void WatcherStrat(string path, string filter)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = path; watcher.Filter = filter; watcher.Changed += new FileSystemEventHandler(OnProcess);
watcher.Created += new FileSystemEventHandler(OnProcess);
watcher.Deleted += new FileSystemEventHandler(OnProcess);
watcher.Renamed += new RenamedEventHandler(OnRenamed); watcher.EnableRaisingEvents = true;
} private static void OnProcess(object source, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Created)
{
OnCreated(source, e);
}
else if (e.ChangeType == WatcherChangeTypes.Changed)
{
OnChanged(source, e);
}
else if (e.ChangeType == WatcherChangeTypes.Deleted)
{
OnDeleted(source, e);
}
} private static void OnCreated(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件新建事件处理逻辑");
} private static void OnChanged(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件改变事件处理逻辑");
} private static void OnDeleted(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件删除事件处理逻辑");
} private static void OnRenamed(object source, RenamedEventArgs e)
{
Console.WriteLine("文件重命名事件处理逻辑");
}
}
}
用上面的方法会发现,在一次文本文件变化的时候OnChanged事件会触发两次,这是因为除了文本内容变化之外还有文件其他的属性也变化了例如修改时间。
为了解决这问题,也便于项目当中实际使用,写了下面几个类来实际使用:
using System;
using System.IO; namespace test
{
class Program
{
static void Main(string[] args)
{
MyFileSystemWather myWather = new MyFileSystemWather(@"C:\test", "*.txt");
myWather.OnChanged += new FileSystemEventHandler(OnChanged);
myWather.OnCreated += new FileSystemEventHandler(OnCreated);
myWather.OnRenamed += new RenamedEventHandler(OnRenamed);
myWather.OnDeleted += new FileSystemEventHandler(OnDeleted);
myWather.Start();
//由于是控制台程序,加个输入避免主线程执行完毕,看不到监控效果
Console.ReadKey();
} private static void OnCreated(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件新建事件处理逻辑");
} private static void OnChanged(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件改变事件处理逻辑");
} private static void OnDeleted(object source, FileSystemEventArgs e)
{
Console.WriteLine("文件删除事件处理逻辑");
} private static void OnRenamed(object source, RenamedEventArgs e)
{
Console.WriteLine("文件重命名事件处理逻辑");
}
}
}
WatcherProcess类:
using System.IO; namespace test
{
public class WatcherProcess
{
private object sender;
private object eParam; public event RenamedEventHandler OnRenamed;
public event FileSystemEventHandler OnChanged;
public event FileSystemEventHandler OnCreated;
public event FileSystemEventHandler OnDeleted;
public event Completed OnCompleted; public WatcherProcess(object sender, object eParam)
{
this.sender = sender;
this.eParam = eParam;
} public void Process()
{
if (eParam.GetType() == typeof(RenamedEventArgs))
{
OnRenamed(sender, (RenamedEventArgs)eParam);
OnCompleted(((RenamedEventArgs)eParam).FullPath);
}
else
{
FileSystemEventArgs e = (FileSystemEventArgs)eParam;
if (e.ChangeType == WatcherChangeTypes.Created)
{
OnCreated(sender, e);
OnCompleted(e.FullPath);
}
else if (e.ChangeType == WatcherChangeTypes.Changed)
{
OnChanged(sender, e);
OnCompleted(e.FullPath);
}
else if (e.ChangeType == WatcherChangeTypes.Deleted)
{
OnDeleted(sender, e);
OnCompleted(e.FullPath);
}
else
{
OnCompleted(e.FullPath);
}
}
}
}
}
MyFileSystemWather类:
using System;
using System.Collections;
using System.IO;
using System.Threading; namespace test
{ public delegate void Completed(string key); public class MyFileSystemWather
{
private FileSystemWatcher fsWather; private Hashtable hstbWather; public event RenamedEventHandler OnRenamed;
public event FileSystemEventHandler OnChanged;
public event FileSystemEventHandler OnCreated;
public event FileSystemEventHandler OnDeleted; /// <summary>
/// 构造函数
/// </summary>
/// <param name="path">要监控的路径</param>
public MyFileSystemWather(string path, string filter)
{
if (!Directory.Exists(path))
{
throw new Exception("找不到路径:" + path);
} hstbWather = new Hashtable(); fsWather = new FileSystemWatcher(path);
// 是否监控子目录
fsWather.IncludeSubdirectories = false;
fsWather.Filter = filter;
fsWather.Renamed += new RenamedEventHandler(fsWather_Renamed);
fsWather.Changed += new FileSystemEventHandler(fsWather_Changed);
fsWather.Created += new FileSystemEventHandler(fsWather_Created);
fsWather.Deleted += new FileSystemEventHandler(fsWather_Deleted);
} /// <summary>
/// 开始监控
/// </summary>
public void Start()
{
fsWather.EnableRaisingEvents = true;
} /// <summary>
/// 停止监控
/// </summary>
public void Stop()
{
fsWather.EnableRaisingEvents = false;
} /// <summary>
/// filesystemWatcher 本身的事件通知处理过程
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void fsWather_Renamed(object sender, RenamedEventArgs e)
{
lock (hstbWather)
{
hstbWather.Add(e.FullPath, e);
} WatcherProcess watcherProcess = new WatcherProcess(sender, e);
watcherProcess.OnCompleted += new Completed(WatcherProcess_OnCompleted);
watcherProcess.OnRenamed += new RenamedEventHandler(WatcherProcess_OnRenamed);
Thread thread = new Thread(watcherProcess.Process);
thread.Start();
} private void WatcherProcess_OnRenamed(object sender, RenamedEventArgs e)
{
OnRenamed(sender, e);
} private void fsWather_Created(object sender, FileSystemEventArgs e)
{
lock (hstbWather)
{
hstbWather.Add(e.FullPath, e);
}
WatcherProcess watcherProcess = new WatcherProcess(sender, e);
watcherProcess.OnCompleted += new Completed(WatcherProcess_OnCompleted);
watcherProcess.OnCreated += new FileSystemEventHandler(WatcherProcess_OnCreated);
Thread threadDeal = new Thread(watcherProcess.Process);
threadDeal.Start();
} private void WatcherProcess_OnCreated(object sender, FileSystemEventArgs e)
{
OnCreated(sender, e);
} private void fsWather_Deleted(object sender, FileSystemEventArgs e)
{
lock (hstbWather)
{
hstbWather.Add(e.FullPath, e);
}
WatcherProcess watcherProcess = new WatcherProcess(sender, e);
watcherProcess.OnCompleted += new Completed(WatcherProcess_OnCompleted);
watcherProcess.OnDeleted += new FileSystemEventHandler(WatcherProcess_OnDeleted);
Thread tdDeal = new Thread(watcherProcess.Process);
tdDeal.Start();
} private void WatcherProcess_OnDeleted(object sender, FileSystemEventArgs e)
{
OnDeleted(sender, e);
} private void fsWather_Changed(object sender, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Changed)
{
if (hstbWather.ContainsKey(e.FullPath))
{
WatcherChangeTypes oldType = ((FileSystemEventArgs)hstbWather[e.FullPath]).ChangeType;
if (oldType == WatcherChangeTypes.Created || oldType == WatcherChangeTypes.Changed)
{
return;
}
}
} lock (hstbWather)
{
hstbWather.Add(e.FullPath, e);
}
WatcherProcess watcherProcess = new WatcherProcess(sender, e);
watcherProcess.OnCompleted += new Completed(WatcherProcess_OnCompleted);
watcherProcess.OnChanged += new FileSystemEventHandler(WatcherProcess_OnChanged);
Thread thread = new Thread(watcherProcess.Process);
thread.Start();
} private void WatcherProcess_OnChanged(object sender, FileSystemEventArgs e)
{
OnChanged(sender, e);
} public void WatcherProcess_OnCompleted(string key)
{
lock (hstbWather)
{
hstbWather.Remove(key);
}
}
}
}
使用了线程安全的Hashtable来处理一次改变触发两次事件的问题,要注意的是在实际项目使用中,在通过监控文件事情触发时开一个线程WatcherProcess去处理自己业务逻辑的时候,不管业务逻辑成功或者失败(例如有异常抛出一定要try一下)一定要让WatcherProcess的 Completed也就是MyFileSystemWather的WatcherProcess_OnCompleted执行去移除对应变化文件的Hashtable的key,不然下次此文件改变时是无法触发你的业务逻辑的。
FileSystemWatcher的更多相关文章
- 利用FileSystemWatcher实现磁盘文件监控
马上放假了,好开森啊O(∩_∩)O哈哈~ ——————————————————————————————————————————————————————— 昨天逛园子,发现了一个FileSystemWa ...
- 使用FileSystemWatcher监控文件夹及文件
引言 这一周主要精力集中学习一个同事开发的本地文件搜索项目上,其中客户端添加共享文件时主要是使用FileSystemWatcher 监控文件,并在各种事件发生时向服务器发送消息. 解决方法 FileS ...
- C# FileSystemWatcher监听文件事件
现有一个需求如下:监控某个目录中的文件修改,创建,删除等信息,并记录下来. 这里用到FileSystemWatcher类.由于考虑到文件的写入量会很频率,所以考虑先将监听到的消息记录到内存中. 监听部 ...
- C#回顾 - 2.NET的IO:Path、File、FileInfo、Directory、DirectoryInfo、DriveInfo、FileSystemWatcher
1.管理文件系统 一般而言,应用程序都会有保存数据.检索数据的需求. 1.1 使用 path 类来访问文件路径 [path常用的方法]:http://www.cnblogs.com/tangg ...
- FileSystemWatcher用法详解
FileSystemWatcher控件主要功能: 监控指定文件或目录的文件的创建.删除.改动.重命名等活动.可以动态地定义需要监控的文件类型及文件属性改动的类型. 1.常用的几个基本属性: (1) P ...
- 在C#使用文件监控对象FileSystemWatcher的几种方案
最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给web服务 ...
- FileSystemWatcher触发多次Change事件的解决办法 .
最近要用到FileSystemWatcher来监控某个目录中的文件是否发生改变,如果改变就执行相应的操作.但在开发过程中,发现FileSystemWatcher在文件创建或修改后,会触发多个Creat ...
- C# 之 FileSystemWatcher事件多次触发的解决方法
1.问题描述 程序里需要监视某个目录下的文件变化情况: 一旦目录中出现新文件或者旧的文件被覆盖,程序需要读取文件内容并进行处理.于是使用了下面的代码: public void Initial() { ...
- 使用文件监控对象FileSystemWatcher实现数据同步
最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给WEB服务 ...
随机推荐
- HDU-1520 Anniversary party(树形DP)
题目大意:一棵树,每个节点都带权.从中取出一些节点,并且子节点不能与父节点同时取,求能取得的最大值. 题目分析:定义状态dp(u,0/1)表示u点不取/取.则状态转移方程为: dp(u,1)=sum( ...
- IE6 7 8BUG锦集
1.浮动元素的双倍margin 说明:这是IE6及其以下版本的一个经典的BUG,触发这个BUG产生的条件是给元素设置了浮动并且同一方向设置了margin值.来看以下代码: <style type ...
- 【HNOI2004】【P1365】L语言
tire水题,%Menci 原题: 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章.一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成. ...
- /usr/include/gnu/stubs.h:7:27: error: gnu/stubs-32.h:No such file or directory的解决办法
在编译32位HDecode时出现如题所示的错误,原因时没有安装32位glibc库导致的: ubuntu: sudo apt-get install libc6-dev-i386 CentOS:yum ...
- #你好Unity3D#Hierarchy视图监听gameObject点击事件
今天无意间又找到了个好方法 1 2 3 4 5 6 7 8 9 10 [InitializeOnLoadMethod] static void Start () { Selection.s ...
- C#中的static、readonly与const的比较
C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景. 工作原理 readonly为运行时常量,程序运 ...
- sql server 排序规则
/* 排序规则根据特定语言和区域设置的标准指定对 字符串 数据 进行排序和比较的规则. 以 ORDER BY 子句为例:如果按升序排列,说英语的人认为字符串 Chiapas 应排在 Col ...
- linux服务之snmp
背景信息 http://datatracker.ietf.org/doc/rfc1213/ http://oid-info.com/get/1.3.6.1 http://oid-info.com/ge ...
- unity,下面两个协程不等价
//代码1 IEnumerator A(){ Debug.Log(“hi1”); { yield return new WaitForSeconds(1f); Debug.Log(“hi2”); } ...
- OpenJudge计算概论-单词倒排【把句子内单词的顺序翻转】
/*================================================== 单词倒排 总时间限制: 1000ms 内存限制: 65536kB 描述 编写程序,读入一段英文 ...