Home » Questions » Computers [ Ask a new question ]

How do I use Java to read from a file that is actively being written to?

How do I use Java to read from a file that is actively being written to?

"I have an application that writes information to file. This information is used post-execution to determine pass/failure/correctness of the application. I'd like to be able to read the file as it is being written so that I can do these pass/failure/correctness checks in real time.

I assume it is possible to do this, but what are the gotcha's involved when using Java? If the reading catches up to the writing, will it just wait for more writes up until the file is closed, or will the read throw an exception at this point? If the latter, what do I do then?

My intuition is currently pushing me towards BufferedStreams. Is this the way to go?"

Asked by: Guest | Views: 336
Total answers/comments: 4
Guest [Entry]

"Could not get the example to work using FileChannel.read(ByteBuffer) because it isn't a blocking read. Did however get the code below to work:

boolean running = true;
BufferedInputStream reader = new BufferedInputStream(new FileInputStream( ""out.txt"" ) );

public void run() {
while( running ) {
if( reader.available() > 0 ) {
System.out.print( (char)reader.read() );
}
else {
try {
sleep( 500 );
}
catch( InterruptedException ex ) {
running = false;
}
}
}
}

Of course the same thing would work as a timer instead of a thread, but I leave that up to the programmer. I'm still looking for a better way, but this works for me for now.

Oh, and I'll caveat this with: I'm using 1.4.2. Yes I know I'm in the stone ages still."
Guest [Entry]

"If you want to read a file while it is being written and only read the new content then following will help you achieve the same.

To run this program you will launch it from command prompt/terminal window and pass the file name to read. It will read the file unless you kill the program.

java FileReader c:\myfile.txt

As you type a line of text save it from notepad and you will see the text printed in the console.

public class FileReader {

public static void main(String args[]) throws Exception {
if(args.length>0){
File file = new File(args[0]);
System.out.println(file.getAbsolutePath());
if(file.exists() && file.canRead()){
long fileLength = file.length();
readFile(file,0L);
while(true){

if(fileLength<file.length()){
readFile(file,fileLength);
fileLength=file.length();
}
}
}
}else{
System.out.println(""no file to read"");
}
}

public static void readFile(File file,Long fileLength) throws IOException {
String line = null;

BufferedReader in = new BufferedReader(new java.io.FileReader(file));
in.skip(fileLength);
while((line = in.readLine()) != null)
{
System.out.println(line);
}
in.close();
}
}"
Guest [Entry]

"You might also take a look at java channel for locking a part of a file.

http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html

This function of the FileChannel might be a start

lock(long position, long size, boolean shared)

An invocation of this method will block until the region can be locked"
Guest [Entry]

"I totally agree with Joshua's response, Tailer is fit for the job in this situation. Here is an example :

It writes a line every 150 ms in a file, while reading this very same file every 2500 ms

public class TailerTest
{
public static void main(String[] args)
{
File f = new File(""/tmp/test.txt"");
MyListener listener = new MyListener();
Tailer.create(f, listener, 2500);

try
{
FileOutputStream fos = new FileOutputStream(f);
int i = 0;
while (i < 200)
{
fos.write((""test"" + ++i + ""\n"").getBytes());
Thread.sleep(150);
}
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}

private static class MyListener extends TailerListenerAdapter
{
@Override
public void handle(String line)
{
System.out.println(line);
}
}
}"