OSDN Git Service

ファイルの追加/削除がリアルタイムで検知できない問題に対応
authoryukihane <yukihane.feather@gmail.com>
Sat, 3 Sep 2011 02:13:57 +0000 (11:13 +0900)
committeryukihane <yukihane.feather@gmail.com>
Fri, 9 Sep 2011 11:41:38 +0000 (20:41 +0900)
frontend/src/yukihane/inqubus/filewatch/FileWatch.java

index 32dc197..472d0e5 100644 (file)
@@ -1,17 +1,20 @@
 package yukihane.inqubus.filewatch;
 
+import static java.nio.file.StandardWatchEventKinds.*;
+
 import java.io.IOException;
 import java.nio.file.DirectoryStream;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.StandardWatchEventKinds;
 import java.nio.file.WatchEvent;
 import java.nio.file.WatchEvent.Kind;
 import java.nio.file.WatchKey;
 import java.nio.file.WatchService;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -32,7 +35,7 @@ public final class FileWatch implements Runnable {
 
         this.files = new HashSet<>(res.files);
         this.directories = new HashSet<>(res.dirs);
-        if(logger.isLoggable(Level.FINER)) {
+        if (logger.isLoggable(Level.FINER)) {
             logger.log(Level.FINER, "search dirs: {0}", directories);
             logger.log(Level.FINER, "exist files: {0}", files);
         }
@@ -73,32 +76,45 @@ public final class FileWatch implements Runnable {
     @Override
     public void run() {
         logger.log(Level.FINER, "FileWatch start");
+        final Map<WatchKey, Path> keys = new HashMap<>();
         try {
             final WatchService ws = FileSystems.getDefault().newWatchService();
             for (Path p : directories) {
-                p.register(ws, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);
+                final WatchKey key = p.register(ws, ENTRY_CREATE, ENTRY_DELETE);
+                keys.put(key, p);
             }
 
             while (true) {
                 final WatchKey wk = ws.take();
+
+                final Path dir = keys.get(wk);
+                if (dir == null) {
+                    System.err.println("WatchKey not recognized!!");
+                    continue;
+                }
+
                 for (final WatchEvent<?> event : wk.pollEvents()) {
                     final Kind<?> kind = event.kind();
-                    if (kind.equals(StandardWatchEventKinds.ENTRY_CREATE)) {
+
+                    if (kind == OVERFLOW) {
+                        continue;
+                    }
+
+                    if (kind == ENTRY_CREATE) {
                         final Path p = (Path) event.context();
-                        // FIXME isRegularFile だとファイルであると認識してくれない…?
-                        if (Files.isRegularFile(p)) {
-                            logger.log(Level.FINER, "ファイル追加: {0}", p);
+                        final Path target = dir.resolve(p);
+                        if (Files.isRegularFile(target)) {
+                            logger.log(Level.FINER, "ファイル追加: {0}", target);
                             synchronized (files) {
-                                files.add(p);
+                                files.add(target);
                             }
                         }
-                    } else if (kind.equals(StandardWatchEventKinds.ENTRY_DELETE)) {
+                    } else if (kind == ENTRY_DELETE) {
                         final Path p = (Path) event.context();
-                        if (Files.isRegularFile(p)) {
-                            logger.log(Level.FINER, "ファイル削除: {0}", p);
-                            synchronized (files) {
-                                files.remove(p);
-                            }
+                        final Path target = dir.resolve(p);
+                        logger.log(Level.FINER, "ファイル削除: {0}", target);
+                        synchronized (files) {
+                            files.remove(target);
                         }
                     }
                 }