Watch for file updates

Hi, I have to detect changes in 5 local text files, and then read each changed file.How can I do it in an efficient way?thanx
[146 byte] By [txatia] at [2007-11-27 6:43:41]
# 1

You would read the file(s) in a continuos loop, saving the contents of each file in separate temporary variable. When, after a reading a file, the new content and the temporary content do not match, then the text file has changed. This is just a line of thought which you can make your code work first before putting efficiency int it.

ARTHUR

Jamwaa at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 2
You could use a Java.util.timer to check at certain intervals. How often do you need to check?If you need to know straight away then the loop wouldbe the best choice but for every 15 minutes or so you would need a timer.
_helloWorld_a at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 3

You gotta create a Thread which will monitor the files for you. You detect any changes by comparing the last modified time value for every file you are watching. Whenever this value is updated to a more recent value, then you know there are some changes to read from that file. You can implement an EventListener which will allow for interested classes to register for this event.

Finally, make sure you put your Thread to sleep after every check for something like 500ms so that it doesn't eat your CPU.

Dalzhima at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 4
I did a folder watcher before using Thread object. The thread method is a resource hog. The javax.swing.Timer method is better.
Jamwaa at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 5

> I did a folder watcher before using Thread object.

> The thread method is a resource hog. The

> javax.swing.Timer method is better.

Yep. They brought timers into Java for requirements like this.

Threads should only be used when you need concurrency, here you don't.

_helloWorld_a at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 6

> I did a folder watcher before using Thread object.

> The thread method is a resource hog. The

> javax.swing.Timer method is better.

javax.swing.Timer uses java.util.Timer internally which uses a Thread internally.

here's the concerned piece of code:

/**

* This "helper class" implements the timer's task execution thread, which

* waits for tasks on the timer queue, executions them when they fire,

* reschedules repeating tasks, and removes cancelled tasks and spent

* non-repeating tasks from the queue.

*/

class TimerThread extends Thread {

The Thread method isn't a resource hog as long as it is used properly. Besides, using javax.swing.Timer doesn't bring any required features when the OP could simply use java.util.Timer.

Dalzhima at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 7
I need to read the changes as they are written, but I don't want to stress the CPU.Is there a more efficient / automatic way to watch the files than i.e. reading every 50 msec? This is the only way I know.
txatia at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 8

There are platfom-specific ways to do this.

1) JNI

2) Exec an external program which makes this and communicate somehow with it, like reading its output in a thread and notifying the rest of the program when an event notification was read. The external program would detect the file-changed event (in a platform-specific way) and write a notification to its stdout.)

BIJ001a at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 9
If you're writing a Swing application consider to build the application on the NetBeans Platform (a RCP API). I think its Filesystem API already provides your required functionality.-Puce
Pucea at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 10
This application has no GUI at this moment.I would like to implement the same functionality as a text editor, that detects in real time that the file been edited at that moment has been modified out of the application.
txatia at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 11

This program watches for file updates in a folder

/*

* Main.java

*

* Created on Jun 5, 2007, 2:05:14 PM

*

* To change this template, choose Tools | Template Manager

* and open the template in the editor.

*/

package forumtester;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import javax.swing.JOptionPane;

import javax.swing.Timer;

import javax.swing.UIManager;

public class Main

{

// A directory that the change is to be detected

static String folderToWatch = "C:\\";

private static File file = new File(folderToWatch);

// An array to hold the list of files in the directory above

private static String[] listOfFiles;

public static void main(String[] args) throws Exception

{

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

// Popilate the array

listOfFiles = file.list();

// Inner class that does the actual detection

class ChangeListener implements ActionListener

{

public void actionPerformed(ActionEvent event)

{

// After the delay specified by the timer constructor, check on what files are currently

// In the folder and store the value in a new array

String[] newListOfFiles = file.list();

System.gc();

// If the size of the new array is larger than the old array, a new file is detected

if(newListOfFiles.length > listOfFiles.length)

{

// This is the StringBuffer object to hold the contents of the file

StringBuffer text = new StringBuffer();

// I dont know if this is always the case, but is has worked quite perfectly

// The new file is the last item of the NEW array

String nameOfNewFile = newListOfFiles[newListOfFiles.length - 1];

System.out.println("New file detected: " + nameOfNewFile);

try

{

// This is to read the contents of the new file and hold them in the String object declared above

File inputFile = new File(folderToWatch + file.separator + nameOfNewFile);

FileReader in = new FileReader(inputFile);

BufferedReader buff= new BufferedReader(in);

String line; // <<-- added

while ((line = buff.readLine()) != null) //

{

text.append(line).append('\n'); //

}

in.close();

// Finally display the name of the new file in a JOptionPane

JOptionPane.showMessageDialog(null, inputFile.getAbsolutePath(), "New file",

JOptionPane.INFORMATION_MESSAGE);

}

catch (Exception e)

{

JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.ERROR_MESSAGE);

}

// Then set the old array to be equal to the new array so as to be able to detect new files

listOfFiles = newListOfFiles;

}

else

{

System.gc();

}

}

}

// Timer with 1 second (1000 millisecond) loop

Timer t = new Timer(1000, new ChangeListener());

t.start();

// The program will run in a continuous loop till you quit

JOptionPane.showMessageDialog(null, "Quit?");

System.exit(0);

}

}

Jamwaa at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 12
Any solution that could work like "tail" command in Unix?I mean, reading from a text file only the added lines?Is there any Java class able to throw an event if the Reader, Stream or File has new lines?Thx
txatia at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 13
On this subject, speaking of platform-specific solutions, anyone know how to get Windows to update you when a file is modified or added?
tjacobs01a at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 14

> Any solution that could work like "tail" command in

> Unix?

> I mean, reading from a text file only the added

> lines?

> Is there any Java class able to throw an event if the

> Reader, Stream or File has new lines?

>

> Thx

Try modify the code to read a buffer of the file contents instead of a directory as above.

Jamwaa at 2007-7-12 18:14:40 > top of Java-index,Java Essentials,Java Programming...
# 15
Anyone has used the java.nio.channels.Selector class?Could be used for this?Any documentation available?
txatia at 2007-7-21 22:03:49 > top of Java-index,Java Essentials,Java Programming...
# 16

> Any solution that could work like "tail" command in

> Unix?

> I mean, reading from a text file only the added

> lines?

> Is there any Java class able to throw an event if the

> Reader, Stream or File has new lines?

>

Store the old file length, then skip to the first byte beyond it when you progress.

malcolmmca at 2007-7-21 22:03:49 > top of Java-index,Java Essentials,Java Programming...