1 package yukihane.inqubus.filewatch;
3 import java.io.IOException;
4 import java.nio.file.DirectoryStream;
5 import java.nio.file.FileSystems;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.nio.file.StandardWatchEventKinds;
9 import java.nio.file.WatchEvent;
10 import java.nio.file.WatchEvent.Kind;
11 import java.nio.file.WatchKey;
12 import java.nio.file.WatchService;
13 import java.util.Collection;
14 import java.util.HashSet;
16 import java.util.logging.Level;
17 import java.util.logging.Logger;
23 public final class FileWatch implements Runnable {
25 private static final Logger logger = Logger.getLogger(FileWatch.class.getName());
26 private final Set<Path> files;
27 private final Set<Path> directories;
29 public FileWatch(Collection<Path> dirs) {
30 FileDir res = new FileDir();
31 getFileDir(dirs, res);
33 this.files = new HashSet<>(res.files);
34 this.directories = new HashSet<>(res.dirs);
35 if(logger.isLoggable(Level.FINER)) {
36 logger.log(Level.FINER, "search dirs: {0}", directories);
37 logger.log(Level.FINER, "exist files: {0}", files);
41 public Set<Path> getFiles() {
42 synchronized (files) {
43 return new HashSet<>(files);
47 private void getFileDir(Iterable<Path> paths, FileDir result) {
48 for (Path p : paths) {
49 getFileDir(p, result);
53 private void getFileDir(Path path, FileDir result) {
55 if (Files.isDirectory(path)) {
56 result.dirs.add(path);
57 DirectoryStream<Path> dir = Files.newDirectoryStream(path);
58 getFileDir(dir, result);
59 } else if (Files.isRegularFile(path)) {
60 result.files.add(path);
62 } catch (IOException ex) {
63 logger.log(Level.WARNING, "パスの処理中にエラー: {0}", new Object[]{path});
67 private static class FileDir {
69 private final Set<Path> files = new HashSet<>();
70 private final Set<Path> dirs = new HashSet<>();
75 logger.log(Level.FINER, "FileWatch start");
77 final WatchService ws = FileSystems.getDefault().newWatchService();
78 for (Path p : directories) {
79 p.register(ws, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
83 final WatchKey wk = ws.take();
84 for (final WatchEvent<?> event : wk.pollEvents()) {
85 final Kind<?> kind = event.kind();
86 if (kind.equals(StandardWatchEventKinds.ENTRY_CREATE)) {
87 final Path p = (Path) event.context();
88 // FIXME isRegularFile だとファイルであると認識してくれない…?
89 if (Files.isRegularFile(p)) {
90 logger.log(Level.FINEST, "ファイル追加: {0}", p);
91 synchronized (files) {
95 } else if (kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
96 final Path p = (Path) event.context();
97 if (Files.isRegularFile(p)) {
98 logger.log(Level.FINEST, "ファイル削除: {0}", p);
99 synchronized (files) {
107 System.out.println("No longer valid");
114 } catch (InterruptedException ex) {
115 ex.printStackTrace();
116 } catch (IOException ex) {
117 ex.printStackTrace();