1

特定のディレクトリとそのサブディレクトリでファイルの変更を傍受する必要がある現在の要件を評価しようとしています。私の要件に合ったツールは、jpathwatch と jnotify です。jpathwatch は機能しますが、再帰的なディレクトリ ウォッチはサポートされていません。Jnotify は、その制限にうまく対処しているように見えました。

jnotify を評価しているときに、奇妙な動作を観察しました。これは、Linux と Windows の両方で一貫しています。例を挙げて説明してみましょう。次のディレクトリ構造があります。


C:
|--> Temp |
          | --> File |
                     | --> Dir |
                               | --> SubDir

jNotify は C:/Temp/File をリッスンするように構成されています。これで、「Dir」または「SubDir」フォルダーの下にファイルをドロップすると、イベントが新しく作成されたものとしてキャプチャされます。ただし、同時に 3 つのファイル変更イベントが発生します。「SubDir」フォルダーに新しいファイル Extraction.log を追加したときの出力を次に示します。


created C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log
modified C:/Temp/File/Dir/SubDir/Extraction.log

ご覧のとおり、ファイルの変更には 3 つのイベントがあります。アプリケーションには、それが変更なのか新しいファイルの作成なのかを判断する手段がありません。したがって、同じファイルを 4 回処理します。

JNotify Web サイトに示されているサンプル コードを使用しています。


package com.test.io;

import net.contentobjects.jnotify.JNotify;

public class JNotifyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        JNotifyTest jNotify = new JNotifyTest();
        try {
            jNotify.sample();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    private void sample() throws Exception {
        // path to watch

        String path = "C:\\Temp\\File\\";

        // watch mask, specify events you care about,
        // or JNotify.FILE_ANY for all events.
        int mask = JNotify.FILE_CREATED  | 
        JNotify.FILE_DELETED  | 
        JNotify.FILE_MODIFIED | 
        JNotify.FILE_RENAMED;

        // watch subtree?
        boolean watchSubtree = true;

        // add actual watch
        int watchID = JNotify.addWatch(path, mask, watchSubtree, new Listener());

        // sleep a little, the application will exit if you
        // don't (watching is asynchronous), depending on your
        // application, this may not be required
        Thread.sleep(1000000);

        // to remove watch the watch
        boolean res = JNotify.removeWatch(watchID);
        if (!res) {
            // invalid watch ID specified.
        }
    }

    class Listener implements JNotifyListener {
        public void fileRenamed(int wd, String rootPath, String oldName,
                String newName) {
            System.out.println("renamed " + rootPath + oldName + " -> " + newName);
        }
        public void fileModified(int wd, String rootPath, String name) {
            System.out.println("modified " + rootPath + name);
        }
        public void fileDeleted(int wd, String rootPath, String name) {
            System.out.println("deleted " + rootPath + name);
        }
        public void fileCreated(int wd, String rootPath, String name) {
            System.out.println("created " + rootPath + name);
        }
    }
}

残念ながら、1.6 で立ち往生しているため、jdk 1.7 を使用できません。

jNotify に関連する投稿はほとんど見たことがありません。誰かがこの要件に対処するためのポインターまたは代替ソリューションを提供してくれれば、本当に感謝しています。

ありがとう

4

1 に答える 1

0

これはおそらく jNotify の問題ではなく、OS がファイル作成を処理する方法によるものです。pynofityPythonのライブラリでも同様のことが起こっているのを見てきました。トリガー処理を数秒遅らせるなどして、アプリケーション コードでこれを処理する必要があります。これにより、新しいイベントがあればバッファリングして、特定のタイプの最新のイベントのみを処理できます。

于 2012-10-09T05:22:12.633 に答える