ammon has asked for the wisdom of the Perl Monks concerning the following question:
When not using the 'follow' or 'follow_fast' options, however, there is no such guarantee of lstat() being called -- it may be called, or it may not be, and, consequently, you can't rely on the underline stat cache containing the stat info of the current file. You have to do it yourself.
In a typical file tree that I'm trawling, I'm finding that File::Find has not done a stat() call on about 80% of the files. The other 20% of files have had a stat() call done prior to the wanted() function call. On one set of test data, that 20% represents 6800+ files. Our filesystem gets too much wear and tear already, so I'd like to avoid duplicating those stat calls when File::Find has already done them.
Edit: How can I know whether File::Find has called lstat() or not?
My first thought is, at the end of my wanted() function, to clear the _ cache. That doesn't seem to be possible, aside from doing something like -l q() (it appears that the lstat() system call simply returns ENOENT when passed an empty string, without going to the filesystem). Is there a better way of invalidating the contents of _? The perlfunc documentation mentions how it gets set, but I haven't yet found anything which indicates that cached data can ever be reset, other than by another call to a stat or filetest.
My second question is a direct consequence of clearing _: is it possible to detect that _ is, or is not, a valid stat cache? My current method is:
my ($dev, $inode) = do { no warnings; lstat _ }; ($dev, $inode) = lstat $_ unless $dev;
Without the no warnings, I get a warning stating lstat() on unopened filehandle _. Unfortunately, I can't find any documentation that indicates any way to test if _ is valid. I thought I might be able to check the defined-ness of *::_{FILEHANDLE}, but was wrong (it generates a warning about being deprecated, and always returns an IO::Handle object. I also tried the simpler
but that generates an error saying Bareword "_" not allowed while "strict subs" in use.my ($dev, $inode) = _ ? lstat _ : lstat $_;
Any suggestions are welcome.
Cheers,
|
|---|