czhiでデータ同期を実現する方法(ファイル監視対象filesystem watchを使用)


最近プロジェクトの中でこのような需要があって、リアルタイムである不規則な変更のテキストファイルの中の内容を取得しなければなりません。まず考えたのは、プログラムで定期的にこのファイルにアクセスすることです。リアルタイム性が要求されているため、間隔は1 Sを超えてはいけません。しかもテキストを取得するたびに、WEBサーバに配布して別の操作をします。そのテキストの書き込みは頻繁になり、1秒で何度も可能ですが、かなり長い間、何の書き込みもない可能性があります。
このように、毎秒ファイルにアクセスすると、一つはIOの問題であり、あとは操作のたびにバックエンドの一連のプログラムの反応を引き起こし、テキストは長い間書かないと、一秒に一度の無駄を触発することは望ましくない。
最终的にc荌の中のFileSystem Watchオブジェクトを発见しました。FileSystem Watchを使う前に、まずこの対象の基本的な属性と事件を理解して、まずFileSystem Watch基本的な知识を普及させます。
FileSystem Watchベース
属性:
Path――この属性はFileSystem Watchにどの経路を監視する必要があるかを教えます。例えば、この属性を「C:\test」に設定すると、オブジェクトは、testディレクトリのすべてのファイルに発生する変更(削除、変更、作成、名前変更を含む)を監視します。
Include SubDirectores――この属性は、FileSystem Watchオブジェクトがサブディレクトリ(すべてのファイル)の変化を監視するべきかどうかを説明しています。
Filter――この属性は、ある種類のファイルの変化をフィルタすることができます。例えば、TXTファイルが変更されたり、新規作成されたり、削除されたりする時だけに通知を提出したいなら、この属性を「**txt」に設定してもいいです。高流量や大規模なディレクトリを扱う時に、この属性を使うのはとても便利です。
NotifyFilter――監視する変更タイプを取得または設定します。ウォッチ.NotifyFilter=NotifyFilters.LastAccess|NotifyFilters.LastWriteなどの更なるフィルタリングが可能です。
|NotifyFilters.FileName|NotifyFilters.DirectoryName;
イベント:
Chenged――監視されているディレクトリの中にファイルが修正された場合、このイベントを提出します。注意すべきなのは、このイベントは何度も提出されるかもしれません。たとえファイルの内容が一つだけ変わっても。これはファイルを保存する際に、ファイルの他の属性も変更されたからです。
Created――監視されているディレクトリにファイルを新規作成すると、このイベントを提出します。新しいイベントをこのイベントで移動するつもりなら、エラー処理コードをイベントプロセッサに書き込んでください。現在のファイルが他のプロセスで使用されている場合を処理できます。というのは、Createdイベントは、ファイルを作るプロセスがファイルを解放する前に提出される可能性があるからです。このような状況を正しく処理するためのコードが用意されていないと、異常が発生する可能性があります。
Deleted――監視されているディレクトリの中からファイルが削除されたら、このイベントを提出します。
Renamed――監視されているディレクトリの中にファイルが名前を変えられたら、このイベントを提出します。
注:EnbleRaisingEventsを真に設定していないと、システムはイベントを提出しません。もしFileSystem Watchのオブジェクトが動作しない場合は、まずEnbaleRaisingEventsを確認して、それが本物に設定されていることを確認してください。
イベントハンドリングは、FileSystem Watchがイベントプロセッサを呼び出したとき、二つの引数――一つは「sender」というオブジェクトと、「e」というFileSystemEventAgsオブジェクトを含む。私たちの関心のある自己変数はFileSystem EventArgs引数です。このオブジェクトには、事件を提出する理由が含まれています。以下はFileSystem EventArgsオブジェクトのいくつかの属性です。
属性:Name――この属性でイベントを提出させるファイルの名前。ファイルのパスは含まれていません。イベントを使用して提出されたファイルまたはディレクトリ名だけが含まれています。
どのタイプのイベントを提出するべきかを指摘しています。その有効値は以下を含む。
Changed
Created
Deleted
Renamed
この属性には、ファイル名とディレクトリ名が含まれています。
注意:FileSystemEventAgsオブジェクトは、監視フォルダの下にファイルが作成、削除、修正された時の引数です。名前を変更するとRenamedEventAgsオブジェクトです。この時はFileSystemEventArgsオブジェクトの属性値を除いて、OldFulPathが一つ増えています。名前を変更する前のファイル名です。
以上はFileSystem EventArgsの基本的な知識で、ほとんどはネットで検索して自分で少し整理しました。
以下は簡単な使い方です。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = @"C:\test";
            watcher.IncludeSubdirectories = true;
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                                   | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = "*.txt";

            watcher.Changed += (s,e1)=> this.Dispatcher.Invoke(new Action(() =>
            {
                label1.Content = e1.Name + " !";
            }));
            watcher.Created += (s, e1) =>  this.Dispatcher.Invoke(new Action(() => { label1.Content = e1.Name + " !"; }));
            watcher.Deleted += (s, e1) =>  this.Dispatcher.Invoke(new Action(() => { label1.Content = e1.Name + " !"; }));
            watcher.Renamed += (s, e1) =>  this.Dispatcher.Invoke(new Action(() =>
            {
                label1.Content = e1.OldName + " :"+e1.Name;
            }));

            //
            watcher.EnableRaisingEvents = true;
        }
    }
}