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
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.
> 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.
> 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.
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.)
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);
}
}
> 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.
> 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.