我正在使用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();
}
}
}
答案 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();
}
}
请参阅ExecutorService和Executors.newSingleThreadExecutor()之类的Future.cancel(),以提高灵活性。
或者,您可以take()
所有事件,并根据volatile boolean
忽略它们。