예제 #1
0
 private void notifyListeners(File file) {
   // listeners is a synchronized list - no need to sync here
   for (FileWatcherListener listener : listeners) {
     try {
       listener.fileChanged(file);
     } catch (Exception e) {
       logger.info(
           "Discarding exception " + e.getLocalizedMessage() + " thrown by FileWatcherListener");
     }
   }
 }
예제 #2
0
  public void run() {

    // now that thread is running, check that directory exists
    // doing this test here allows it to be created subsequent to the file watcher construction
    if (!dir.exists()) {
      throw new RuntimeException("FileWatcher directory path does not exist[" + dir + "]");
    }

    for (FileWatcherListener listener : listeners) {
      listener.startedWatching(dir);
    }

    // record time we started polling
    long startPollTime = System.currentTimeMillis();

    for (; ; ) {
      logger.debug("starting directory poll {}", dir);

      // has an external thread requested that this one be stopped?
      if (stopHasBeenRequested()) {
        logger.info("stopping file watcher thread");
        break;
      }

      // scan directory for files or directories we are interested in
      File[] files =
          dir.listFiles(
              new FileFilter() {
                public boolean accept(File file) {
                  boolean isDir = file.isDirectory();
                  if (watchDirs != isDir) return false;

                  return file.getName().matches(nameRegexp);
                }
              });

      // find directory entries that have been changed since previous poll
      // note: given that even the retrieval of the last modified time can consume time
      // (let alone any actions in the notifications), it is not safe to just compare the
      // current last modified time of each file against a single time for the end of the
      // previous poll - instead we maintain a record of the previous modification time
      // for any file which has been modified during the lifetime of this poller
      // then compare the current last modified time against that
      for (File file : files) {
        logger.debug("found " + file.getName());

        // find previous known last modified time for file
        Long prevModifiedTime = prevModifiedTimeByFile.get(file);
        if (prevModifiedTime == null) {
          // we do not know about this file - this means that it had not previously
          // been modified since we started polling so use start of polling as its
          // previous modification time
          prevModifiedTimeByFile.put(file, prevModifiedTime = startPollTime);
          logger.debug("no previous modification time for file {}", file);
        } else if ((System.currentTimeMillis() - prevModifiedTime) > MAX_TIME_SINCE_LAST_MODIFIED) {
          // the last time this file was modified since we started up this poller
          // was over (default) a day ago - we can't possibly get confused over a
          // modification time that long ago so get rid of file from cache
          prevModifiedTimeByFile.remove(file);
          logger.debug("cache entry expired, ignoring file {}", file);
          continue;
        }
        logger.debug("prevModifiedTime={} for file {}", prevModifiedTime, file);

        long lastModifiedTime = file.lastModified();
        logger.debug("lastModifiedTime={} for file {}", lastModifiedTime, file);
        if (lastModifiedTime > prevModifiedTime) {
          notifyFileChange(file);
          prevModifiedTimeByFile.put(file, lastModifiedTime);
        }
      }

      try {
        Thread.sleep(pollingIntervalMillis);
      } catch (InterruptedException exp) {
      }
    }
  }