1

I want to run a task if there is a trigger (i.e. Some event like new file added to directory) in Java. Does Java have inbuilt support for this? If not, what third party library I can use to facilitate this?

Amrendu Pandey
  • 91
  • 1
  • 12
Bourne
  • 1,905
  • 13
  • 35
  • 53

3 Answers3

1

In Java 7 there is the Watch Service that allows a task to happen when a change or event is detected on a file or directory.

Tutorial: http://docs.oracle.com/javase/tutorial/essential/io/notification.html#overview

API documentation: http://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html

Here is a quick example I've cooked up:

package watcher;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

public class Watcher {

    private final FileCreatedAction action;
    private final String pathToWatchString;

    public Watcher(FileCreatedAction action, String pathToWatchString) {
        this.action = action;
        this.pathToWatchString = pathToWatchString;
    }

    public void start() throws IOException {
        FileSystem defaultFileSystem = FileSystems.getDefault();
        WatchService watchService = defaultFileSystem.newWatchService();
        Path pathToWatch = defaultFileSystem.getPath(pathToWatchString);
        pathToWatch.register(watchService, StandardWatchEventKinds.ENTRY_CREATE);
        while(true) {
            try {
                WatchKey key = watchService.take();
                if (key != null) {
                    for (WatchEvent<?> event: key.pollEvents()) {
                        if (event.kind().equals(StandardWatchEventKinds.ENTRY_CREATE))
                        {
                            WatchEvent<Path> ev = (WatchEvent<Path>)event;
                            Path filename = ev.context();
                            Path fullFilename = pathToWatch.resolve(filename);
                            action.performAction(fullFilename);
                        }
                    }
                }
            } catch (InterruptedException error) {
                return;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        FileCreatedAction action = new FileCreatedAction() {

            @Override
            public void performAction(Path fullPath) {
                System.out.printf("Found file %s", fullPath);
            }
        };

        Watcher watcher = new Watcher(action, "/foo");
        watcher.start();
    }

}

interface FileCreatedAction {
    void performAction(Path fullPath);
}
Adrian Jarvis
  • 66
  • 1
  • 6
  • Is there a way to avoid the continuous looping? I mean I want to basically have a Action class and the Trigger class (with method isTriggered()) which could be a new file added and execute the action when the trigger is true. – Bourne Feb 04 '14 at 08:59
  • For the trigger class look at the StandardWatchEventKinds. The WatchService method take() avoids having to have a busy wait loop. – Adrian Jarvis Feb 05 '14 at 07:43
0

You could easily implement your own file system tracker. There's a nice, working example in here:

How to watch the file system for changes in Java 7 (JDK 7)

Community
  • 1
  • 1
pubsy
  • 166
  • 1
  • 9
0

Generally, what you need is a design pattern called 'Observer Pattern'. You can implement your own, without needing any inbuilt support or external frameworks.

For inbuilt support, check Java's 'util' package for 'Observer' and EventListener (since Java 7) interfaces.

Also, check the following links:

1) Generic, annotation-driven event notification frameworks

2) Alternative to Java's Observable class?

Community
  • 1
  • 1
bchetty
  • 2,231
  • 1
  • 19
  • 26