Cheetah
Cheetah

Reputation: 14379

Read a file that is being written to by another process

I have a file that is being written to by another process (completely different pid). I know it is writing to the file line-by-line.

From Java, I would like to read this file line-by-line as the lines are being written to it. (or as close as I can get to that).

Rather than re-inventing the wheel...is there already a common way to achieve this in Java? It would be nice to have a blocking function called .readLine().

Upvotes: 0

Views: 397

Answers (1)

blo0p3r
blo0p3r

Reputation: 6850

You can use a WatchService to observe events from your operating system.

I prefer the option using the take method since it prevents your system from polling needlessly and waits for events from your operating system.

I have used this successfully on Windows, Linux and OSX - as long as Java 7 is available since this is a new feature since JDK 1.7.

Here is the solution I came up with - running in a different thread than the main thread since I didn't want this to block my UI - but this is up to you and your application architecture.

boolean run = true;
WatchService watchService = FileSystems.getDefault().newWatchService();
Path watchingPath = Paths.get("path/to/your/directory/to/watch");
watchingPath.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);

WatchKey key = null;
while(run && !isCancelled()) {
    try {
        key = watchService.take();
        for(WatchEvent<?> event : key.pollEvents()) {
            if(!isCancelled()) {
                if(event.context().toString().equals(fileName)) {
                    //Your file has changed, do something interesting with it.
                }
            }
        }
    } catch (InterruptedException e) {
        //Failed to watch for result file cahnges
        //you might want to log this.
        run = false;
    } catch (ClosedWatchServiceException e1) {
        run = false;
    }
    
    boolean reset = key.reset();
    if(!reset) {
        run = false;
    }
}

See Also

Upvotes: 1

Related Questions