FileSystem Watch

27700 ワード

回転:http://www.cnblogs.com/zhaojingjing/archive/2011/01/21/1941586.html
注意:FileWatchのCreatedでファイルを監視すると、ファイルが作成された直後にCreatedをトリガします.ファイルはまだ書き込みが完了していません.ファイルも完全なファイルではありません.Image.FroomFileで先ほど傍受したファイルをロードすると、「メモリ不足」という異常が発生します.
以下は簡単な使い方です.
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("           ");
        }
    }
}
上記の方法では、一度のテキストファイルの変更時に、OnChendイベントが2回トリガされることが分かります.テキストの内容の変化以外に、ファイルの他の属性も変更されています.例えば、修正時間がかかります.
この問題を解決するために、プロジェクトの中で実際に使うのにも便利です.
 主な方法:、
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("           ");
        }
    }
}
Watch Processクラス:
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);
                }
            }
        }
    }
}
MyFileSystem Watherクラス:
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を使用して、一回の変更によって二回のイベントが発生する問題を処理します.実際のプロジェクトでは、ファイルを監視することによって触発された時に、スレッドWatch Processを開いて、自分の業務ロジックを処理する場合、業務ロジックの成功や失敗(例えば、異常があったらtryを投げてください)に関わらず、必ずWatcherProcessを実行させます. Copletedとは、MyFileSystem WatherのWatch Processです.OComplettedは、変化するファイルに対応するhashtableのkeyを削除します.そうでないと、今度このファイルが変更された時、あなたのビジネスロジックを触発することができません.