Can anyone tell me if Ruby’s File.ctime can be reliably
used to detect if a directory’s contents have changed?
I do not need to know of changes to files, just adds and
deletes of files to/from the directory itself.
I have tested this on FreeBSD and OpenBSD and both seem
to indicate my expected behaviour (although File.mtime
does not)–if anyone can try other platforms or knows
offhand, the information would be appreciated. Windows
is not a concern.
In case you are curious, I intend to cache the files under
$PATH and only re-access them if a modification has been
detected. Alternative solutions to this are also welcome.
Can anyone tell me if Ruby’s File.ctime can be reliably
used to detect if a directory’s contents have changed?
I do not need to know of changes to files, just adds and
deletes of files to/from the directory itself.
On Linux, File.ctime(path) can be used on a directory to detect file
additions or removals, but not changes to existing files.
Example code:
#!/usr/bin/ruby
path="/temp2"
ot = File.ctime(path)
while true
nt = File.ctime(path)
puts “#{path} changed at #{Time.new}” if nt != ot
ot = nt
sleep 1
end
In case you are curious, I intend to cache the files under
$PATH and only re-access them if a modification has been
detected.
Okay, now you are saying “modification”, not addition or removal. On
Linux,
File.ctime won’t flag change in the directory when file contents change,
only additions or removals.
BTW File.mtime and File.ctime appear to act the same under Linux.
Alternative solutions to this are also welcome.
You want to monitor a directory of files for changes and act if one or
more
of them has changed, yes? Why not simply collect stats on all the files
periodically, and compare new times with old for each file?
Can anyone tell me if Ruby’s File.ctime can be reliably
used to detect if a directory’s contents have changed?
I do not need to know of changes to files, just adds and
deletes of files to/from the directory itself.
On Linux, File.ctime(path) can be used on a directory to detect file
additions or removals, but not changes to existing files.
Excellent, this is just what I needed to know.
Example code:
#!/usr/bin/ruby
path="/temp2"
ot = File.ctime(path)
while true
nt = File.ctime(path)
puts “#{path} changed at #{Time.new}” if nt != ot
ot = nt
sleep 1
end
In case you are curious, I intend to cache the files under
$PATH and only re-access them if a modification has been
detected.
Okay, now you are saying “modification”, not addition or removal. On
Linux,
File.ctime won’t flag change in the directory when file contents change,
only additions or removals.
No, I am sorry for mixing terms. I needed to monitor additions
and removals which (in my addled brain are modifications of the
directory ‘file’ itself).
BTW File.mtime and File.ctime appear to act the same under Linux.
Alternative solutions to this are also welcome.
You want to monitor a directory of files for changes and act if one or
more
of them has changed, yes? Why not simply collect stats on all the files
periodically, and compare new times with old for each file?
I have to be assured that my cache is up-to-date, so I
check the ctime each time anything in that directory
is invoked–if there has been a change, I re-cache the
directory.
I have to be assured that my cache is up-to-date, so I
check the ctime each time anything in that directory
is invoked–if there has been a change, I re-cache the
directory.
Well, I ran my little program and added and removed files from the
target
directory, with a printout on each change, so it appears to work for the
Linux kernel. Many Unices and similar operating systems will behave the
same.
Good question, to which I don’t have a general answer. I assumed that the
handling of file times were rather central to the identity of an operating
system (rather than a filesystem). It’s just an assumption.
The operating system just reports what the filesystem tells it.
Consider the example where you have a distributed file system.
The computer which is doing the Stat call may not be the same
computer which added some file to the directory. It is only the
information stored in the filesystem itself which can be seen on
both systems.
I expect your trick would work in very many situations, but there
are some uncommon situations where the trick might not work.
This is particularly likely if dealing with distributed filesystems like
NFS or AFS, or if the path you are checking is in some kind of
“union” filesystem. The trick might even work in those situations,
but I can also imagine that it might not.
Actually, won’t this behavior depend on the file system rather than the
kernel?
I don’t know about ctime, but some filesystems allow control over
whether other attributed like atime are maintained or updated.
Good question, to which I don’t have a general answer. I assumed that
the
handling of file times were rather central to the identity of an
operating
system (rather than a filesystem). It’s just an assumption.
Yes, I agree. I thought I would add something I remember from NFS (or
perhaps its predecessor filesystem FAT32) – it registers file times with a
granularity of 2 seconds, not 1 as you might expect. This made me
absolutely crazy when I tried to synchronize a directory on a Windows
machine from a Linux one – the synchronization kept repeating itself
because the times refused to match up. I finally realized Windows wasn’t
playing with a full deck.
And note that you can mount various types of windows file systems in
Linux either directly or via samba.
Some of those actually let you do useful things with them.
I expect your trick would work in very many situations, but there
are some uncommon situations where the trick might not work.
This is particularly likely if dealing with distributed filesystems like
NFS or AFS, or if the path you are checking is in some kind of
“union” filesystem. The trick might even work in those situations,
but I can also imagine that it might not.
Yes, I agree. I thought I would add something I remember from NFS (or
perhaps its predecessor filesystem FAT32) – it registers file times
with a
granularity of 2 seconds, not 1 as you might expect. This made me
absolutely crazy when I tried to synchronize a directory on a Windows
machine from a Linux one – the synchronization kept repeating itself
because the times refused to match up. I finally realized Windows wasn’t
playing with a full deck.
does not)–if anyone can try other platforms or knows
offhand, the information would be appreciated. Windows
is not a concern.
In case you are curious, I intend to cache the files under
$PATH and only re-access them if a modification has been
detected. Alternative solutions to this are also welcome.
this may interest you, we’ve used it in production for years: