3

ファイルへの変更が発生するまでスレッド (メイン/EDT) を待機させ、その後待機させたいと考えています。DefaultFileMonitor は Runnable を拡張するため、独自のスレッドで実行されます。ここにSSCEがあります:

import java.io.File;
import org.apache.commons.vfs.*;
import org.apache.commons.vfs.impl.DefaultFileMonitor;

public class FileChangeListener implements FileListener {
    DefaultFileMonitor fm;
    public final static File logFile = new File("t.txt");

 public void startListening() throws FileSystemException {
    final FileSystemManager fsManager = VFS.getManager();
    final FileObject listendir = fsManager.toFileObject(logFile);

    fm = new DefaultFileMonitor(this);
    fm.addFile(listendir);
    fm.start();
}

     @Override
public void fileCreated(FileChangeEvent fce) throws Exception {
    fileChanged(fce);
}

@Override
public void fileDeleted(FileChangeEvent fce) throws Exception {
    //hmm..why deleted?
}

@Override
public void fileChanged(FileChangeEvent fce) throws Exception {
    System.out.println("fileChanged executed");
}
}

メイン:

import java.io.PrintWriter;

public class App {

public static void main(String[] args) {
    FileChangeListener fcl = new FileChangeListener();
    try {
        fcl.startListening();
        final PrintWriter printWriter = new PrintWriter(FileChangeListener.logFile);
        printWriter.println("Hello Threads!");
        printWriter.close();

        //EXECUTE THE FOLLOWING ONLY AFTER fileChanged
        System.out.println("Mission complete.");
    } catch (Exception ex) {
    }
}
}
4

3 に答える 3

2

printWriter.close() の後に App.main(..) に以下を追加します。

            synchronized (fcl) {
                fcl.wait();
            }
            //EXECUTE THE FOLLOWING ONLY AFTER fileChanged
            System.out.println("Mission complete.");

FileChangeListener.fileChanged(..) の System.out.println("fileChanged executable") の後に以下を追加します。

synchronized (this) {
        this.notifyAll();
    }
于 2010-11-08T16:08:51.813 に答える
1

「条件」を使用して2つの間で通信できます:http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html

基本的に、新しい「共有」を作成しますCondition(たとえばfileChanged)。ここで、ファイルが変更されるたびに (fileChanged()この条件をトリガーします ( fileChanged.signal())。メイン コードで、この条件が発生するのを待ちます ( fileChanged.await())。

アイデアが得られることを願っています。


条件を複数のコードユニットにアクセスできるようにするために、ここに私が考えることができるものがあります(優先順位の降順):

  1. リッスンするファイルと同じ数の条件が必要になると仮定して、ファイル (パス、名前、またはその他の属性) に基づいてオブジェクトをgetCondition(String file path/name/attribute)返すファクトリ メソッドを作成します。Conditionこのファクトリ メソッドを使用して、すべてのケースで条件を取得します。ファクトリは、リッスンする新しいファイルごとにインスタンスを内部的に作成new Condition()し、ファイルの処理が完了すると古いインスタンスを破棄する必要があります (したがって、おそらくdestroy/deleteCondition(String file)メソッドも追加する必要があります)。
  2. 条件をpublicフィールドとしてリスナー クラスに保存します (リスナー インスタンスが利用可能な場合はハックのようなものです)。
  3. 条件をpublic staticフィールドとしてリスナー クラスに保存します (リスナー インスタンスが全体で 1 つしかない場合はハックのようなものです)。
于 2010-11-08T08:59:08.080 に答える
0

なんで?FileChangeListener はコールバックです。イベントが発生したときに実行されます。この特定のケースでは、ファイルを閉じたばかりなので、そのファイルでミッションが完了したことはすでにわかっているので、次のステップに進みます。ここで FileChangeListener が必要な理由がまったくわかりません。

于 2010-11-08T09:28:20.383 に答える