Method of Real time Monitoring File Change in Directory Based on Java

  • 2021-07-07 07:24:55
  • OfStack

1. commons-io method

1. The related classes under monitor of Commons-io can handle the monitoring of files, which is realized by observer mode

(1) You can monitor the creation, deletion, and modification of folders (2) You can monitor the creation, deletion and modification of files (3) It is realized by the observer mode (4) Using threads to refresh and detect the changes of files

2. Introducing commons-io package requires more than 2.0.


<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

3. Write the class FileListener that inherits FileAlterationListenerAdaptor.


import java.io.File;
import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.log4j.Logger;
/**
 *  File change listener 
 *  In Apache Adj. Commons-IO There are codes about the monitoring function of files in .  The principle of file monitoring is as follows: 
 *  Monitor classes by files FileAlterationMonitor The thread in the file viewer scans the file viewer constantly FileAlterationObserver , 
 *  If there is a file change, according to the relevant file comparator, judge when the file is added, deleted or changed. (Default to 1000 Millisecond execution 1 Sub-scan) 
 */
public class FileListener extends FileAlterationListenerAdaptor {
  private Logger log = Logger.getLogger(FileListener.class);
  /**
   *  File creation execution 
   */
  public void onFileCreate(File file) {
    log.info("[ New ]:" + file.getAbsolutePath());
  }
  /**
   *  File creation modification 
   */
  public void onFileChange(File file) {
    log.info("[ Modify ]:" + file.getAbsolutePath());
  }
  /**
   *  File deletion 
   */
  public void onFileDelete(File file) {
    log.info("[ Delete ]:" + file.getAbsolutePath());
  }
  /**
   *  Directory creation 
   */
  public void onDirectoryCreate(File directory) {
    log.info("[ New ]:" + directory.getAbsolutePath());
  }
  /**
   *  Directory modification 
   */
  public void onDirectoryChange(File directory) {
    log.info("[ Modify ]:" + directory.getAbsolutePath());
  }
  /**
   *  Directory deletion 
   */
  public void onDirectoryDelete(File directory) {
    log.info("[ Delete ]:" + directory.getAbsolutePath());
  }
  public void onStart(FileAlterationObserver observer) {
    // TODO Auto-generated method stub
    super.onStart(observer);
  }
  public void onStop(FileAlterationObserver observer) {
    // TODO Auto-generated method stub
    super.onStop(observer);
  }
}

4. Implement main method


public static void main(String[] args) throws Exception{
    //  Monitoring directory 
    String rootDir = "D:\\apache-tomcat-7.0.78";
    //  Polling interval  5  Seconds 
    long interval = TimeUnit.SECONDS.toMillis(1);
    //  Create a filter 
    IOFileFilter directories = FileFilterUtils.and(
        FileFilterUtils.directoryFileFilter(),
        HiddenFileFilter.VISIBLE);
    IOFileFilter files    = FileFilterUtils.and(
        FileFilterUtils.fileFileFilter(),
        FileFilterUtils.suffixFileFilter(".txt"));
    IOFileFilter filter = FileFilterUtils.or(directories, files);
    //  Use a filter 
    FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir), filter);
    // Do not use filters 
    //FileAlterationObserver observer = new FileAlterationObserver(new File(rootDir));
    observer.addListener(new FileListener());
    // Create a file change listener 
    FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
    //  Start monitoring 
    monitor.start();
  }

2. Use WatchService provided by JDK7


public static void main(String[] a) {
    final Path path = Paths.get("D:\\apache-tomcat-7.0.78");
    try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
      // To path Path plus file observation service 
      path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
          StandardWatchEventKinds.ENTRY_MODIFY,
          StandardWatchEventKinds.ENTRY_DELETE);
      while (true) {
        final WatchKey key = watchService.take();
        for (WatchEvent<?> watchEvent : key.pollEvents()) {
          final WatchEvent.Kind<?> kind = watchEvent.kind();
          if (kind == StandardWatchEventKinds.OVERFLOW) {
            continue;
          }
          // Create an event 
          if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
            System.out.println("[ New ]");
          }
          // Modification event 
          if (kind == StandardWatchEventKinds.ENTRY_MODIFY) {
            System.out.println(" Modify ]");
          }
          // Delete event 
          if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
            System.out.println("[ Delete ]");
          }
          // get the filename for the event
          final WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
          final Path filename = watchEventPath.context();
          // print it out
          System.out.println(kind + " -> " + filename);
        }
        boolean valid = key.reset();
        if (!valid) {
          break;
        }
      }
    } catch (IOException | InterruptedException ex) {
      System.err.println(ex);
    }
  }

3. All the above methods can realize the file monitoring of the corresponding folder, but there will be some problems when using API provided by jdk7.

(1) When the file is modified, it will be called twice, that is, two identical modifications will be output. (2) You can't monitor its subfolders, and you can only prompt that the directory has been modified. (3) File types cannot be filtered.

Summarize


Related articles: