determining when a file has been moved/changed

R

Rob Baxter

I'm trying to implement a java program which will mirror the
functionality of the Unix utility tail -f (ie continually read the end
of a file). I have a fairly simple solution using FileInputStream &
bufferedReader in an infinite loop where I call Thread.sleep(1000)
every time the read returns null (indicating the end of the
FileInputStream has been reached).

The problem I am having is that I am using this to read the end of a
syslog log file and the files are logrotated every hour. When the
logrotate process renames the file I have opened my program continues
to read from the same file which is no longer being written to by
syslog. What I am looking for is a way to either be notified or be
able to determine when another process has moved/renamed a file I am
reading from. I've tried getting the file descriptor from the
FileInputStream and calling it's valid() method but it always returns
true even if I delete the file after it has been opened.

I know I can rig something up using the filesize to check if the file
has been rotated, but I was wondering if there was a more elegant
solution. any hints or advice are greatly appreciated (also if anyone
knows of a version of tail which doesn't suffer from this same problem
I'd be interested in seeing that also)

TIA,
-rob
 
M

Michael Borgwardt

I doubt you'll find any tail utility that does not have this "problem"
on Unixoid file systems. The real problem is that these file system have
a concept of "file" that goes against your expectations, namely in that
a file and a path are two completely separate things. There is an extra
layer (inode layer) that abstracts files from directory entries, and
a file can be referred by several completely different names in different
directories, or even keep existing when there are no directory entries
pointing to it at all.
 
J

Jacob

Rob said:
I'm trying to implement a java program which will mirror the
functionality of the Unix utility tail -f (ie continually read the end
of a file). I have a fairly simple solution using FileInputStream &
bufferedReader in an infinite loop where I call Thread.sleep(1000)
every time the read returns null (indicating the end of the
FileInputStream has been reached).

The problem I am having is that I am using this to read the end of a
syslog log file and the files are logrotated every hour. When the
logrotate process renames the file I have opened my program continues
to read from the same file which is no longer being written to by
syslog. What I am looking for is a way to either be notified or be
able to determine when another process has moved/renamed a file I am
reading from. I've tried getting the file descriptor from the
FileInputStream and calling it's valid() method but it always returns
true even if I delete the file after it has been opened.

I know I can rig something up using the filesize to check if the file
has been rotated, but I was wondering if there was a more elegant
solution. any hints or advice are greatly appreciated (also if anyone
knows of a version of tail which doesn't suffer from this same problem
I'd be interested in seeing that also)

The FileMonitor class @ http://geosoft.no/software/index.html
might help you out.

If you know the name of the files to monitor, listen for them;
You'll be notified when they're created, modified or deleted.

If you don't know their names, listen at the directory instead.
When it is modified, files have been accessed.
 
O

Oscar kind

Michael Borgwardt said:
I doubt you'll find any tail utility that does not have this "problem"
on Unixoid file systems. The real problem is that these file system have
a concept of "file" that goes against your expectations, namely in that
a file and a path are two completely separate things. There is an extra
layer (inode layer) that abstracts files from directory entries, and
a file can be referred by several completely different names in different
directories, or even keep existing when there are no directory entries
pointing to it at all.

Absolutely correct.

OP: You need to poll the last changed date (a timestamp) using the file path
(and hence a File object), rather than waiting if there is data available
on the InputStream you're reading from.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top