Example #1
0
  /** Check that a cancelled key will never be queued */
  static void testCancel(Path dir) throws IOException {
    System.out.println("-- Cancel --");

    try (WatchService watcher = FileSystems.getDefault().newWatchService()) {

      System.out.format("register %s for events\n", dir);
      WatchKey myKey = dir.register(watcher, new WatchEvent.Kind<?>[] {ENTRY_CREATE});
      checkKey(myKey, dir);

      System.out.println("cancel key");
      myKey.cancel();

      // create a file in the directory
      Path file = dir.resolve("mars");
      System.out.format("create: %s\n", file);
      Files.createFile(file);

      // poll for keys - there will be none
      System.out.println("poll...");
      try {
        WatchKey key = watcher.poll(3000, TimeUnit.MILLISECONDS);
        if (key != null) throw new RuntimeException("key should not be queued");
      } catch (InterruptedException x) {
        throw new RuntimeException(x);
      }

      // done
      Files.delete(file);

      System.out.println("OKAY");
    }
  }
 public synchronized void unwatchPath(File file, final FileChangeCallback callback) {
   PathData data = files.get(file);
   if (data != null) {
     data.callbacks.remove(callback);
     if (data.callbacks.isEmpty()) {
       files.remove(file);
       for (WatchKey key : data.keys) {
         key.cancel();
         pathDataByKey.remove(key);
       }
     }
   }
 }
Example #3
0
 private void rescan() throws IOException {
   try {
     synchronized (processing) {
       while (processing.get() > 0) {
         processing.wait();
       }
     }
     for (WatchKey key : keys.keySet()) {
       key.cancel();
     }
     keys.clear();
     Files.walkFileTree(root, new FilteringFileVisitor());
     synchronized (processing) {
       while (processing.get() > 0) {
         processing.wait();
       }
     }
   } catch (InterruptedException e) {
     throw (IOException) new InterruptedIOException().initCause(e);
   }
 }
Example #4
0
  public void downloadFile(String relPath) {
    VOSync.debug("Downloading file from storage: " + relPath);
    Path filePath = FileSystems.getDefault().getPath(startDir.toString(), relPath.substring(1));
    try {
      WatchKey key =
          filePath.getParent().register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
      keys.remove(key);
      key.cancel();

      FileOutputStream outp = new FileOutputStream(filePath.toFile());
      DropboxFileInfo info = api.getFile(relPath, null, outp, null);
      outp.close();

      key = filePath.getParent().register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
      keys.put(key, filePath.getParent());

      MetaHandler.setFile(relPath, filePath.toFile(), info.getMetadata().rev);
    } catch (IOException ex) {
      logger.error("Error downloading file " + relPath + ": " + ex.getMessage());
    } catch (DropboxException ex) {
      ex.printStackTrace();
      logger.error("Error downloading file " + relPath + ": " + ex.getMessage());
    }
  }
Example #5
0
  /**
   * @param path Path to monitor.
   * @param fileEncoding Encoding for reading the file
   * @param listener Handler for detected events.
   * @throws IOException Errors other than {@link NoSuchFileException}.
   */
  public void watch(Path path, Charset fileEncoding, FileModificationListener listener)
      throws IOException {
    // Read file from beginning.
    fileEndPosition = 0;
    watching = true;

    WatchService ws;

    if (!Files.exists(path)) {
      listener.noSuchFile(path);
    }

    try {
      ws = path.getFileSystem().newWatchService();
      logger.debug("Using Java WatchService.");
    } catch (UnsupportedOperationException e) {
      logger.debug("Falling back to polling.");
      // File system does not support watching.
      polling(path, fileEncoding, listener);
      // Polling is infinite.
      return;
    }

    // Watching is likely supported.
    Kind<?>[] kinds = {
      StandardWatchEventKinds.ENTRY_CREATE,
      StandardWatchEventKinds.ENTRY_DELETE,
      StandardWatchEventKinds.ENTRY_MODIFY
    };

    while (watching) {
      // Acquire a watch as close to the monitored file as possible.
      Path closestExisting = getClosestWatchable(path);
      Path watchToDesiredWatch = closestExisting.relativize(path.getParent());
      boolean watchingDesired = closestExisting.equals(path.getParent());
      WatchKey key = null;
      try {
        logger.debug("Start watching " + closestExisting);
        key = closestExisting.register(ws, kinds);
      } catch (Exception e) {
        logger.error("Failed to register watch on " + closestExisting, e);
      }
      if (key == null) {
        throw new NotWatchableException();
      }
      if (Files.exists(path)) {
        // Process new files (either newly created or available due to
        // parent folder moves).
        examineFile(path, fileEncoding, listener);
      }
      awaitKeys:
      while (watching) {
        WatchKey res = null;
        try {
          // Await the presence of new events on the watched folder.
          res = ws.take();

          for (WatchEvent<?> candidate : res.pollEvents()) {
            // Skip over unknown events.
            if (candidate.kind() == StandardWatchEventKinds.OVERFLOW) {
              logger.debug("Java lost events, checking for additions to monitored file.");
              // Java lost events. Make sure to process existing
              // file to avoid missing additions.
              if (Files.exists(path)) {
                examineFile(path, fileEncoding, listener);
              }
              continue;
            }

            @SuppressWarnings("unchecked")
            WatchEvent<Path> event = (WatchEvent<Path>) candidate;

            if (watchingDesired) {
              // Already watching desired folder, see if monitored
              // files is affected.
              if (event.context().getName(0).equals(path.getFileName())) {
                // Something happened to the monitored file.
                if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE
                    || event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) {
                  logger.debug(path + " was created or modified.");
                  // Read the file's content and notify
                  // listener.
                  examineFile(path, fileEncoding, listener);
                } else if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) {
                  logger.debug(path + " was deleted.");
                  listener.noSuchFile(path);
                }
              }
            } else {
              // Not yet watching desired folder.
              if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
                if (event.context().getName(0).equals(watchToDesiredWatch.getName(0))) {
                  logger.debug("More specific path to monitor available.");
                  // Path towards monitored file created,
                  // dispose current watch and try to get a
                  // closer watch.
                  res.cancel();
                  res = null;
                  break awaitKeys;
                }
              }
            }
          }
        } catch (InterruptedException e) {
          logger.error("Interrupted waiting for watch event.", e);
          break;
        } finally {
          if (res != null && res.reset() == false) {
            logger.debug("Aborting watch on " + closestExisting + " as it is no longer watchable.");
            break;
          }
        }
      }
    }
  }