NonSoft

フォルダを監視(ファイルの追加/変更/削除)する
サンプル(C#.NET)


 サンプル(ソース/コード)
<このサンプルの概要>
フォルダ内のファイルを監視してファイルが新規作成、更新、削除された事を監視するサンプルです。
指定フォルダ以下の全てのファイルを監視します。

関連するツールはこちらです。
・PC状況メール通知(PcEvMail)
 PC起動/PC終了/ログイン/ログアウト/ファイル更新時にメール通知/ログ出力するツールです。
・ファイル監視人
 ファイルやフォルダの更新時にメッセージ表示またはメール送信するツールです。
・フォルダ監視人
 フォルダ内のファイル更新時に更新通知(差分メール等)、指定プログラム実行するツールです。

このサンプルはSystem.IO.DirectoryInfoを使用しフォルダ内のファイル一覧を取得しています。
そのファイル一覧を使用してファイル追加チェックおよびファイル削除チェックをしています。
System.IO.File.GetLastWriteTimeを使用してファイルの更新日時チェックをしています。

ファイルが更新された事をすぐに知りたいと言う要望を聞く事があり、
そんな時にこのサンプルが役に立つかも知れません。

VB.NET版はこちらです。
フォルダを監視(ファイルの追加/変更/削除)するサンプル(VB.NET)

★フォーム・クラス(Form1.cs)
public partial class Form1 : Form
{
    private String fpath;       // 監視するフォルダPATH
    private String[] flist_old; // 監視するフォルダ内のファイル一覧(PATH,更新日時)

    // フォームロード時に監視フォルダの初期処理
    private void Form1_Load(object sender, EventArgs e)
    {
        // 監視するフォルダPATH設定 
        fpath = @"D:\Temp\Test";

        // 監視するフォルダ内のファイル一覧取得(PATH,更新日時)
        flist_old = GetFList(fpath);
    }

    // タイマーで監視フォルダの変更チェック
    private void timer1_Tick(object sender, EventArgs e)
    {
        // 監視するフォルダ内のファイル一覧取得(PATH,更新日時)
        String[] flist_new = GetFList(fpath);

        //' フォルダ内のファイル更新チェック(追加/変更/削除)
        String[] fcmp = FolderCompare(flist_old, flist_new);

        // ファイル更新チェック結果表示 
        for (int i = 0; i <= fcmp.Length - 1; i++)
        {
            String[] kbn = fcmp[i].Split('\t');
            if (kbn[0] != "___")
            {
                System.Diagnostics.Debug.Print("" + (i + 1) + ":" + fcmp[i]);
            }
        }

        // 変更後情報を変更前情報として保存
        flist_old = flist_new;
    }

    // ファイル一覧(PATH,更新日時)を比較し 
    // 比較結果一覧(区分,PATH,更新日時1,更新日時2)を返す
    public String[] FolderCompare(String[] ls1, String[] ls2)
    {

        String fpt = fpath;
        if (fpt.Substring(fpt.Length - 1, 1) != "\\") fpt = fpt + "\\";

        String[] fc = new String[0] { };
        int p1 = 0;
        int p2 = 0;
        while (true)
        {
            // ファイル1の情報(PATH,更新日時)
            String[] fd1 = new String[2] { "", "" };
            // ファイル2の情報(PATH,更新日時)
            String[] fd2 = new String[2] { "", "" };
            // 更新タイプ(0:同じ,1:追加,2:削除,3:更新) 
            int upd = 0;

            if (p1 >= ls1.Length)
            {
                if (p2 >= ls2.Length)
                {
                    // 比較完了
                    break;
                }
                else
                {
                    // 追加ファイル発見
                    fd2 = ls2[p2].Split('\t');
                    // 相対PATHに変換
                    fd2[0] = fd2[0].Replace(fpt, "");
                    upd = 1;
                }
            }
            else if (p2 >= ls2.Length)
            {
                if (p1 >= ls1.Length)
                {
                    // 比較完了
                    break;
                }
                else
                {
                    // 削除ファイル発見
                    fd1 = ls1[p1].Split('\t');
                    // 相対PATHに変換
                    fd1[0] = fd1[0].Replace(fpt, "");
                    upd = 2;
                }
            }
            else
            {
                fd1 = ls1[p1].Split('\t');
                fd2 = ls2[p2].Split('\t');
                // 相対PATHに変換
                fd1[0] = fd1[0].Replace(fpt, "");
                fd2[0] = fd2[0].Replace(fpt, "");
                if (fd1[0].ToLower().CompareTo(fd2[0].ToLower()) > 0)
                {
                    // 追加ファイル発見
                    upd = 1;
                }
                else if (fd1[0].ToLower().CompareTo(fd2[0].ToLower()) < 0)
                {
                    // 削除ファイル発見
                    upd = 2;
                }
                else
                {
                    // ファイルの更新日時を比較する
                    if (upd == 0)
                    {
                        String dt1 = fd1[1];
                        String dt2 = fd2[1];
                        if (dt1 != dt2)
                        {
                            // 更新ファイル発見
                            upd = 3;
                        }
                    }
                }
            }

            // 結果一覧へ追加
            String fn = fd1[0]; // ファイルPATH 
            String od = fd1[1]; // ファイル更新日時1 
            String nd = fd2[1]; // ファイル更新日時2 

            if (upd == 0)
            {
                // 同じファイルの情報
                String recdt = fn + "\t" + od + "\t" + nd;
                Array.Resize<String>(ref fc, fc.Length + 1);
                fc[fc.Length - 1] = "___" + "\t" + recdt;
                p1 += 1;
                p2 += 1;
            }
            else if (upd == 1)
            {
                // 追加ファイルの情報
                fn = fd2[0];
                String recdt = fn + "\t" + "" + "\t" + nd;
                Array.Resize<String>(ref fc, fc.Length + 1);
                fc[fc.Length - 1] = "ADD" + "\t" + recdt;
                p2 += 1;
            }
            else if (upd == 2)
            {
                // 削除ファイルの情報
                String recdt = fn + "\t" + od + "\t" + "";
                Array.Resize<String>(ref fc, fc.Length + 1);
                fc[fc.Length - 1] = "DEL" + "\t" + recdt;
                p1 += 1;
            }
            else if (upd == 3)
            {
                // 更新ファイルの情報
                String recdt = fn + "\t" + od + "\t" + nd;
                Array.Resize<String>(ref fc, fc.Length + 1);
                fc[fc.Length - 1] = "UPD" + "\t" + recdt;
                p1 += 1;
                p2 += 1;
            }
        }
        return fc;
    }

    // フォルダ内のファイル一覧取得(PATH,更新日時)
    private String[] GetFList(String pt)
    {

        String[] ls = new String[0] { };
        String[] l2 = new String[0] { };
        int ln;

        // ファイル一覧/フォルダ一覧取得初期設定
        if (System.IO.Directory.Exists(System.IO.Path.GetPathRoot(pt)))
        {
            // ドライブ存在OK
            if (System.IO.File.Exists(pt))
            {
                // 指定ファイル初期設定
                Array.Resize<String>(ref ls, 1);
                ls[0] = pt;
            }
            else if (System.IO.Directory.Exists(pt))
            {
                // 指定フォルダ初期設定
                Array.Resize<String>(ref ls, 1);
                ls[0] = pt;
                ln = ls[0].Length;
                if (ls[0].Substring(ln - 1) != "\\")
                {
                    ls[0] = ls[0] + "\\";
                }
                GetFList_Sub(pt, ref ls);
                // ファイル名の昇順
                Array.Sort(ls);
            }
        }
        else
        {
            // ドライブ存在NG
            throw new Exception("Drive Not Found(" + System.IO.Path.GetPathRoot(pt) + ")");
        }

        // ファイルの更新日時取得
        for (int i = 0; i <= ls.Length - 1; i++)
        {
            String fp = ls[i];
            ln = ls[i].Length;
            if (ls[i].Substring(ln - 1) != "\\")
            {
                // ファイルのみ一覧に加える
                System.IO.FileInfo fi = new System.IO.FileInfo(ls[i]);
                String df = "yyyy/MM/dd HH:mm:ss";
                String dt = fi.LastWriteTime.ToString(df);
                Array.Resize<String>(ref l2, l2.Length + 1);
                // タブ区切り(PATH,更新日時)
                l2[l2.Length - 1] = fp + "\t" + dt;
            }
        }
        return l2;
    }

    // 再帰的にフォルダ内のファイル一覧取得(PATH,更新日時)
    private void GetFList_Sub(String pt, ref String[] ls)
    {

        // フォルダの情報取得
        System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(pt);

        // ファイルの一覧取得
        System.IO.FileInfo[] sf = di.GetFiles();
        for (int i = 0; i <= sf.Length - 1; i++)
        {
            Array.Resize<String>(ref ls, ls.Length + 1);
            ls[ls.Length - 1] = sf[i].FullName;
        }

        // フォルダの一覧取得
        System.IO.DirectoryInfo[] sd = di.GetDirectories();
        for (int i = 0; i <= sd.Length - 1; i++)
        {
            Array.Resize<String>(ref ls, ls.Length + 1);
            ls[ls.Length - 1] = sd[i].FullName + "\\";
            String[] sds = new String[0] { };
            GetFList_Sub(sd[i].FullName, ref sds);
            for (int j = 0; j <= sds.Length - 1; j++)
            {
                Array.Resize<String>(ref ls, ls.Length + 1);
                ls[ls.Length - 1] = sds[j];
            }
        }
    }
}