1 package yukihane.inqubus.filewatch;
3 import static java.nio.file.StandardWatchEventKinds.*;
5 import java.io.IOException;
6 import java.nio.file.DirectoryStream;
7 import java.nio.file.FileSystems;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10 import java.nio.file.WatchEvent;
11 import java.nio.file.WatchEvent.Kind;
12 import java.nio.file.WatchKey;
13 import java.nio.file.WatchService;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.HashSet;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
26 public final class FileWatch implements Runnable {
28 private static final Logger logger = LoggerFactory.getLogger(FileWatch.class);
29 private final Set<Path> files;
30 private final Set<Path> directories;
32 public FileWatch(Collection<Path> dirs) {
33 FileDir res = new FileDir();
34 getFileDir(dirs, res);
36 this.files = new HashSet<>(res.files);
37 this.directories = new HashSet<>(res.dirs);
38 if (logger.isDebugEnabled()) {
39 logger.debug("search dirs: {}", directories);
40 logger.debug("exist files: {}", files);
44 public Set<Path> getFiles() {
45 synchronized (files) {
46 return new HashSet<>(files);
50 private void getFileDir(Iterable<Path> paths, FileDir result) {
51 for (Path p : paths) {
52 getFileDir(p, result);
56 private void getFileDir(Path path, FileDir result) {
58 if (Files.isDirectory(path)) {
59 result.dirs.add(path);
60 DirectoryStream<Path> dir = Files.newDirectoryStream(path);
61 getFileDir(dir, result);
62 } else if (Files.isRegularFile(path)) {
63 result.files.add(path);
65 } catch (IOException ex) {
66 logger.warn("パスの処理中にエラー: {}", path);
70 private static class FileDir {
72 private final Set<Path> files = new HashSet<>();
73 private final Set<Path> dirs = new HashSet<>();
78 logger.debug("FileWatch start");
79 final Map<WatchKey, Path> keys = new HashMap<>();
81 final WatchService ws = FileSystems.getDefault().newWatchService();
82 for (Path p : directories) {
83 final WatchKey key = p.register(ws, ENTRY_CREATE, ENTRY_DELETE);
88 final WatchKey wk = ws.take();
90 final Path dir = keys.get(wk);
92 System.err.println("WatchKey not recognized!!");
96 for (final WatchEvent<?> event : wk.pollEvents()) {
97 final Kind<?> kind = event.kind();
99 if (kind == OVERFLOW) {
103 if (kind == ENTRY_CREATE) {
104 final Path p = (Path) event.context();
105 final Path target = dir.resolve(p);
106 if (Files.isRegularFile(target)) {
107 logger.debug("ファイル追加: {}", target);
108 synchronized (files) {
112 } else if (kind == ENTRY_DELETE) {
113 final Path p = (Path) event.context();
114 final Path target = dir.resolve(p);
115 logger.debug("ファイル削除: {}", target);
116 synchronized (files) {
117 files.remove(target);
123 System.out.println("No longer valid");
130 } catch (InterruptedException ex) {
131 ex.printStackTrace();
132 } catch (IOException ex) {
133 ex.printStackTrace();