Monitor Directory Changes

The javaxt.io.Directory class includes a getEvents() method that can be used to monitor and detect changes made to a directory. On Windows machines, the Directory class leverages a JNI to get instant notifications of changes made to the file system. On UNIX systems, the class crawls through the file system periodically to find changes. The getEvents() method does not rely on Java's WatchService API so it is compatible with older versions of Java (e.g. Java 1.6).

Event Types

There are 4 different categeories of events that are returned by the getEvents() method:

  • CREATE
  • MODIFY
  • RENAME
  • DELETE

Example

Here's a simple example of how to use the Directory.getEvents() method. In this example, we will watch for all events made to a directory and print out any changes. Note that the monitor is fully recursive.

    javaxt.io.Directory directory = new javaxt.io.Directory("/");
    java.util.List events = directory.getEvents();
    while (true){

        javaxt.io.Directory.Event event;
        synchronized (events) {
            while (events.isEmpty()) {
              try {
                  events.wait();
              }
              catch (InterruptedException e) {
              }
            }

            event = events.remove(0);
        }

        if (event!=null){

            System.out.println(event.toString());

          //Compare files before/after the event
            if (event.getEventID()==event.RENAME){
                System.out.println(
                    event.getOriginalFile() + " vs " + event.getFile()
                );
            }
        }

    }

Sync Folder Example

In this example, we will perform a one-way sync between the source directory and the destination. Whenever a file or directory is created, modified, or deleted in the source directory, we will update the destination directory.


    private static void sync(javaxt.io.Directory source, javaxt.io.Directory destination) throws Exception {

      //Create an event que
        java.util.List events = source.getEvents();

      //Process events
        while (true){

            Event event;

          //Wait for new events to be added to the que
            synchronized (events) {
                while (events.isEmpty()) {
                  try {
                      events.wait();
                  }
                  catch (InterruptedException e) {}
                }
                event = (Event) events.remove(0);
            }


          //Process event
            int eventID = event.getEventID();
            if (eventID==Event.DELETE){

              //Build path to the file in the destination directory
                String path = destination + event.getFile().substring(source.toString().length());

              //Delete the file/directory
                new java.io.File(path).delete();
            }
            else{

              //Check if the event is associated with a file or directory so
              //we can use the JavaXT classes to create or modify the target.
                java.io.File obj = new java.io.File(event.getFile());
                if (obj.isDirectory()){
                    javaxt.io.Directory dir = new javaxt.io.Directory(obj);
                    javaxt.io.Directory dest = new javaxt.io.Directory(destination + dir.toString().substring(source.toString().length()));

                    switch (eventID) {

                        case (Event.CREATE): dir.copyTo(dest, true); break;
                        case (Event.MODIFY): break; //TODO
                        case (Event.RENAME): {
                            javaxt.io.Directory orgDir = new javaxt.io.Directory(event.getOriginalFile());
                            dest = new javaxt.io.Directory(destination + orgDir.toString().substring(source.toString().length()));
                            dest.rename(dir.getName());
                            break;
                        }
                    }

                }
                else{
                    javaxt.io.File file = new javaxt.io.File(obj);
                    javaxt.io.File dest = new javaxt.io.File(destination + file.toString().substring(source.toString().length()));

                    switch (eventID) {

                        case (Event.CREATE): file.copyTo(dest, true); break;
                        case (Event.MODIFY): file.copyTo(dest, true); break;
                        case (Event.RENAME): {
                            javaxt.io.File orgFile = new javaxt.io.File(event.getOriginalFile());
                            dest = new javaxt.io.File(destination + orgFile.toString().substring(source.toString().length()));
                            dest.rename(file.getName());
                            break;
                        }
                    }

                }
            }

        }

    }