使用监视文件夹重新启动线程

时间:2018-11-24 17:13:55

标签: java multithreading key watchservice

我有一个正在监视设置文件中设置的文件夹的线程。如果更改设置,我想停止线程并使用要查看的实际文件夹启动新线程。这段代码正在“正常”运行,但收到​​一些错误消息。

public static void resetWatch() throws FileNotFoundException, IOException, InterruptedException {
    BufferedReader setup = new BufferedReader(new FileReader(new File("setup\\setup.dat")));
    String DirtoWatch = setup.readLine();

    Path toWatch = Paths.get(DirtoWatch);
    if(toWatch == null) {
        throw new UnsupportedOperationException("Directory not found");
    }

    // make a new watch service that we can register interest in
    // directories and files with.
    myWatcher = toWatch.getFileSystem().newWatchService();

    // start the file watcher thread below
    fileWatcher = new Watcher(myWatcher, toWatch);

    th = new Thread(fileWatcher, "FileWatcher");
    th.start();
    System.out.println("Monitoring " + DirtoWatch + " for changes...");
    // register a file
    toWatch.register(myWatcher, ENTRY_CREATE);
    th.join();
}

Watcher类

public class Watcher implements Runnable {

    private WatchService myWatcher;
    public Path path;
    private WatchKey key;

    public Watcher(WatchService myWatcher, Path path) {
        this.myWatcher = myWatcher;
        this.path = path;
    }

    @Override
    public void run() {
        String evCon;

        try {
            // get the first event before looping
            key = myWatcher.take();
            while(key != null) {

                for (WatchEvent event : key.pollEvents()) {
                    evCon =  event.context().toString();
                    System.out.println("New file: " + evCon);
                    Thread.sleep(500);
                    folder_changed(path.toString() + "/" + evCon);
                }
                key.reset();
                key = myWatcher.take();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException ex) {
            Logger.getLogger(Watcher.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("Stopping thread");
    }

    public void stopThread() {
        try {
            System.out.println("Closing the ws");
            myWatcher.close();
            if(key!=null) {
                key.cancel();  
            }
            Thread.currentThread().interrupt();
        } catch (IOException | ClosedWatchServiceException exc) { System.out.println("Closing thread exception"); }
    }
}

如果更改设置,则会更新安装文件,然后尝试关闭观察程序并再次运行线程:

try{
        fileWatcher.stopThread();
        myWatcher.close();
    }
    catch(ClosedWatchServiceException | IOException ex) { System.out.println("Watch Service exc. "); } 

    try {
        resetWatch();
    } catch (IOException | InterruptedException ex) { System.out.println("Recall resetWatch exc. "); }

然后它“运行”,但是我得到跟随异常,指向监视键:

Monitoring ..path.. for changes...
Closing the ws
Monitoring ..path.. for changes...
Exception in thread "FileWatcher" java.nio.file.ClosedWatchServiceException
Recall resetWatch exc. 
    at sun.nio.fs.AbstractWatchService.checkOpen(AbstractWatchService.java:80)
    at sun.nio.fs.AbstractWatchService.checkKey(AbstractWatchService.java:92)
    at sun.nio.fs.AbstractWatchService.take(AbstractWatchService.java:119)
    at jstockcheck.Watcher.run(Watcher.java:40)
    at java.lang.Thread.run(Thread.java:748)

任何建议如何避免这种错误?谢谢!

1 个答案:

答案 0 :(得分:0)

可以随时调用close方法以关闭服务,从而导致所有等待检索密钥的线程都抛出ClosedWatchServiceException

ClosedWatchServiceException-如果此监视服务已关闭,或者在等待下一个键时已关闭。

对于您而言,我认为这只是在调用take时捕获异常并进行静默处理的问题,例如:

try {
    key = myWatcher.take()
} catch (ClosedWatchServiceException e) {
    continue;
}

这是根据: https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html