2010-05-26 79 views
6

出於某種原因,Perl中保持高速緩存我想要的目錄項讀取使用readdir爲什麼Perl的readdir()緩存目錄條目?

opendir(SNIPPETS, $dir_snippets); # or die... 
while (my $snippet = readdir(SNIPPETS)) 
{ print ">>>".$snippet."\n"; } 
closedir(SNIPPETS); 

由於我的目錄包含兩個文件,test.pltest.man,我期待下面的輸出:

. 
.. 
test.pl 
test.man 

不幸的Perl返回很多已經消失得無影無蹤,例如,因爲我試圖將其重命名的文件。之後我謹test.pltest.yeah Perl會返回以下列表:

. 
.. 
test.pl 
test.yeah 
test.man 

什麼是對這種奇怪的行爲的原因是什麼? opendir,readdirclosedir的文檔沒有提到某種緩存機制。 「ls -l」清楚地列出了只有兩個文件。

+0

兩個'readline'和'readdir'預讀和高速緩存。這是野獸的本質。 – tchrist 2011-02-26 18:13:02

回答

9

opendir的結果似乎是在它被調用時目錄中的文件列表。如果你改變了目錄,你需要調用rewinddir

my $dir_snippets = "/tmp/fruit"; 
system ("rm -rf $dir_snippets"); 
mkdir $dir_snippets or die $!; 
my $banana = "$dir_snippets/banana"; 
system ("touch $banana"); 
opendir(SNIPPETS, $dir_snippets); # or die... 
while (my $snippet = readdir(SNIPPETS)) { 
    if (-f $banana) { 
     unlink $banana; 
     rewinddir SNIPPETS; 
    } 
    print ">>>".$snippet."\n"; 
} 
closedir(SNIPPETS); 

給你

 
>>>. 
>>>. 
>>>.. 

沒有rewinddir你

 
>>>. 
>>>.. 
>>>banana 

只是肝炎測試,我得到同樣的事情:

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <dirent.h> 
#include <errno.h> 

int main() 
{ 
    DIR * fruit; 
    struct dirent * file; 

    fruit = opendir ("/tmp/fruit"); 
    if (! fruit) { 
     fprintf (stderr, "opendir failed: %s\n", strerror (errno)); 
     exit (EXIT_FAILURE); 
    } 
    while (file = readdir (fruit)) { 
     unlink ("/tmp/fruit/banana"); 
     printf (">>> %s\n", file->d_name); 
    } 
    closedir (fruit); 
} 

提供了以下(以「觸摸」創建文件「香蕉」後):

 
$ ./a.out 
>>> . 
>>> .. 
>>> banana 
$ ./a.out 
>>> . 
>>> .. 
+0

哇,現在就像魅力一樣,謝謝!我在腳本的頂部調用了opendir(),期望readdir()能夠完成實際的閱讀。 tl; dr:要麼在readdir之前調用opendir,要麼在您正在讀取的目錄中使用rewinddir。 – 2010-05-26 10:45:47