トップ 履歴 一覧 カテゴリ ソース 検索 ヘルプ RSS ログイン

Source/Java/AutoFsChk

INDEX

ファイルシステムの更新チェック

特定ディレクトリもしくはファイルのファイル更新をチェックする。

 更新自動チェックの方法

チェック処理は、ターゲットのファイルが、変更時刻の一覧になければ「追加されたファイル」、あって時刻が異なるなら「変更されたファイル」、一覧を参照されなかったものが「削除されたファイル」となる。

デーモンスレッドを1つ常駐させて一定間隔でチェック処理を走らせる。デーモンスレッドにすることで、プログラムを終了させるとともにスレッドも終了されます。

更新チェック

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * $Id: AutoFileUpdateCheck.java,v 0.0 2009/09/24 00:00:00 t-imamura Exp $
 *
 * Copyright (c) 2009 t-imamura, All rights reserved.
 */
package autofschk;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Timer;
import java.util.TimerTask;

/**
 * ファイルシステムの更新チェック. <br>
 * 監視対象にファイルを指定した場合は、そのファイルの変更を監視する。
 * 監視対象にディレクトリを指定した場合は、その配下のファイルを監視する。
 *
 * <pre>
 * File checkPath = new File(チェックするファイルもしくはディレクトリ);
 * AutoFileUpdateCheck check = new AutoFileUpdateCheck(chkPath, false, 1000L);
 * // 監視開始
 * check.start();
 * // 監視終了
 * check.stop();
 * </pre>
 */
public class AutoFileUpdateCheck {

    /** 監視用タイマースレッド */
    private static Timer timer;

    static {
        timer = new Timer(true);
    }

    /** 更新の監視対象 */
    private final File target;
    /** 監視対象を再帰的に探す */
    private final boolean recursive;
    /** 更新の監視間隔(ミリ秒) */
    private final long interval;

    /** 監視対象のパスと変更時刻 */
    private HashMap<String, Long> watch;
    /** 監視タイマータスク */
    private UpdateChecker watcher;

    /**
     * AutoFileUpdateCheck を構築する。
     *
     * @param target 監視対象
     * @param recursive 再帰的に探す
     * @param interval 監視間隔
     */
    public AutoFileUpdateCheck(File target, boolean recursive, long interval) {
        this.target = target;
        this.recursive = recursive;
        this.interval = interval;
        this.watch = new HashMap<String, Long>();
    }

    /**
     * 監視を開始する。
     */
    public synchronized void start() {
        // 監視対象の初期化
        this.watch.clear();
        for (File file : getFilse()) {
            if (!file.exists()) continue;
            watch.put(file.getPath(), file.lastModified());
        }
        // 監視タイマー始動
        this.watcher = new UpdateChecker();
        timer.schedule(this.watcher, this.interval, this.interval);
    }

    /**
     * 監視を終了する。
     */
    public synchronized void stop() {
        // 監視タイマー停止
        this.watcher.cancel();
        this.watcher = null;
        // 監視対象の初期化
        this.watch.clear();
    }

    /**
     * 監視対象で変更があった(変更時刻が変わった)ファイル。
     * @param file 該当のファイル
     */
    protected void changedFile(File file) {
        System.out.println("Mod file. path=" + file.getPath());
    }

    /**
     * 監視対象で追加されたファイル。
     * @param file 該当のファイル
     */
    protected void addedFile(File file) {
        System.out.println("Add file. path=" + file.getPath());
    }

    /**
     * 監視対象で削除されたファイル。
     * @param file 該当のファイル
     */
    protected void deletedFile(File file) {
        System.out.println("Del file. path=" + file.getPath());
    }

    private synchronized void check() {
        HashSet<String> files = new HashSet<String>(this.watch.keySet());
        for (File file : getFilse()) {
            if (!file.exists()) continue;
            String path = file.getPath();
            long mtime = file.lastModified();
            if (this.watch.containsKey(path)) {
                if (mtime != this.watch.get(path)) {
                    changedFile(file);
                    this.watch.put(path, mtime);
                }
                files.remove(path);
            } else {
                addedFile(file);
                this.watch.put(path, mtime);
            }
        }
        for (String path : files) {
            deletedFile(new File(path));
            this.watch.remove(path);
        }
    }

    private File[] getFilse() {
        if (target.isDirectory()) {
            ArrayList<File> files = new ArrayList<File>();
            addFilse(files, target);
            return files.toArray(new File[0]);
        } else if (target.isFile()) {
            return new File[] { target };
        }
        return new File[0];
    }

    private void addFilse(ArrayList<File> files, File path) {
        for (File file : path.listFiles()) {
            if (recursive && file.isDirectory()) {
                addFilse(files, file);
            } else if (file.isFile()) {
                files.add(file);
            }
        }
        return;
    }

    private class UpdateChecker extends TimerTask {
        public void run() {
            check();
        }
    }

}

テスト兼サンプル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package autofschk;

import java.io.File;

/**
 * ファイルシステムの更新チェック.
 */
public class AutoFileUpdateCheckTest {

    /**
     * アプリケーション.
     * @param args 引数
     * @throws Exception 例外
     */
    public static void main(String[] args) throws Exception {
        File chkPath = new File("C:/Temp/");
        AutoFileUpdateCheck check = new AutoFileUpdateCheck(chkPath, true, 1000);
        check.start();
        Thread.sleep(60*1000L);
        check.stop();
    }

}

参考

最終更新時間:2009年10月24日 16時23分49秒 指摘や意見などあればSandBoxのBBSへ。

AutoFileUpdateCheck.java AutoFileUpdateCheckTest.java