如何暂停观察程序服务,以便我可以更新文件,然后重新启动

时间:2019-04-08 15:42:20

标签: java

我正在使用Watcher服务监视Windows中的目录。如果对文件进行了更改,我想将时间戳记写入同一文件。当然,这是对目录的另一种修改,观察者然后再次处理该事件。有没有一种方法可以挂起观察器,以便我可以更新文件,然后重新启动它以等待下一个事件?

也许有更好的建议?

 package net.codejava.io;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.sql.Timestamp;
import java.util.Date;


public class DirectoryWatchDemo {

    static String logfile = "C:/Temp/log.txt";

    volatile static boolean suspended = false;

    public static void main(String[] args) {
        try {
            WatchService watcher = FileSystems.getDefault().newWatchService();
            Path dir = Paths.get("C:/Temp/");
            dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
            // System.out.println("Watch Service registered for dir: " +
            // dir.getFileName());

            while (true) {
                WatchKey key;
                try {
                    key = watcher.take();
                } catch (InterruptedException ex) {
                    return;
                }

                if (!suspended) {
                    resume();

                } else {
                    updateFile();
                    suspend();

                }

                if (key.isValid())

                    for (WatchEvent<?> event : key.pollEvents()) {
                        WatchEvent.Kind<?> kind = event.kind();

                        @SuppressWarnings("unchecked")
                        WatchEvent<Path> ev = (WatchEvent<Path>) event;
                        Path fileName = ev.context();
                        System.out.println(kind.name() + ": " + fileName);
                    }

                boolean valid = key.reset();
                if (!valid) {
                    System.out.println("Watch service invalid");
                    break;
                }
            }

        } catch (IOException ex) {
            System.err.println(ex);
        }
    }

    private static void suspend() {
        suspended = false;

    }

    private static void resume() {
        suspended = true;

    }

    public static void updateFile() {

        try {
            File outfile = new File(logfile);
            if (!outfile.exists()) {
                System.out.println("No file exists...writing a new file");
                outfile.createNewFile();
            }
            FileWriter fw = new FileWriter(outfile.getAbsoluteFile(), true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write("TimeStamp: " + new Timestamp(new java.util.Date().getTime()).toString() + "\r\n");
            bw.flush();
            bw.close();
            System.out.println("done");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您需要中断正在使用监视服务的线程,因为这是您摆脱watcher.take()的唯一方法。具有老式线程的示例:

public void start() {
    thread = new Thread(directoryWatchDemo::watch);
    thread.start();
}

public void pause() throws InterruptedException {
    if (thread.isAlive()) {
        thread.interrupt();
        thread.join();
    }
}

请参阅ExecutorServiceExecutors.newSingleThreadExecutor()之类的Future.cancel(),以提高灵活性。

或者,您可以take()所有事件,并根据volatile boolean忽略它们。