转: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. JS 的线程、事件循环、任务队列简介

    JS 是单线程的,但是却能执行异步任务,这主要是因为 JS 中存在事件循环(Event Loop)和任务队列(Task Queue). 事件循环:JS 会创建一个类似于 while (true) 的循 ...

  2. json对象和字符串互相转换

  3. android开源项目---项目篇

    本文转载于:http://blog.csdn.net/likebamboo/article/details/19081151 主要介绍那些Android还不错的完整项目,目前包含的项目主要依据是项目有 ...

  4. 查找目录下的所有文件中是否含有某个字符串 linux

    查找目录下的所有文件中是否含有某个字符串 find .|xargs grep -ri "IBM" 查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名 find .|xar ...

  5. java枚举实例

    实例一: public enum OrderOption {ASC,DESC; } 实例二(带参数构造函数): public enum OrderOption { ASC("ASC" ...

  6. Unity3d 适配机型

    1,为了是更多机型能够安装你的游戏,Unity3d Device Filter设置:ARMv6 with VFP: 2,华为C8600,一运行强制停止: 参考网址:http://forum.unity ...

  7. sql server 移动表到文件组

    存储过程如下: USE [SCC_Test_FileGroupAndIndex] GO /****** Object:  StoredProcedure [dbo].[sp_MoveTable]    ...

  8. Java基础试题

      1.使用Java语言编写的源程序保存时的文件扩展名是( B ). (A).class          (B).java            (C).cpp            (D).txt ...

  9. nodejs 任务调度使用

    使用的模块 node-schedule的使用 例子: 1:确定时间 var schedule = require("node-schedule");console.log(&quo ...

  10. Log4j使用详解(log4j.properties格式)

    Log4j使用详解(log4j.properties格式) 1.Log4j 的引入 在应用程序中添加日志记录总的来说基于三个目的: ① 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计 ...