2010-05-26 35 views
6

Đối với một số lý do Perl giữ bộ nhớ đệm các mục thư mục Tôi đang cố gắng để đọc sử dụng readdir:Tại sao các mục nhập thư mục bộ nhớ cache của Perl's readdir()?

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

Kể từ thư mục của tôi chứa hai tập tin, test.pltest.man, tôi đang mong đợi đầu ra sau:

. 
.. 
test.pl 
test.man 

Thật không may Perl trả về nhiều tệp đã bị biến mất, ví dụ vì tôi đã cố đổi tên chúng. Sau khi tôi di chuyển test.pl-test.yeah Perl sẽ trở lại danh sách sau đây:

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

lý do cho hành vi kỳ lạ này là gì? Tài liệu dành cho opendir, readdirclosedir không đề cập đến một số loại cơ chế lưu vào bộ nhớ cache. "ls -l" rõ ràng chỉ liệt kê hai tệp.

+0

Cả đọc trước và đọc trước 'readline' và' readdir'. Đó là bản chất của con thú. – tchrist

Trả lời

9

Kết quả của opendir có vẻ là danh sách các tệp nằm trong thư mục tại thời điểm được gọi. Nếu bạn thay đổi thư mục mà bạn cần phải gọi 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); 

Cung cấp cho bạn

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

Nếu không có sự rewinddir bạn nhận được

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

Chỉ cần thử nghiệm với C, tôi nhận được điều tương tự:

#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); 
} 

Cung cấp thông tin sau (sau khi tạo tệp "chuối" bằng "chạm"):

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

Whoa, hoạt động như sự quyến rũ ngay bây giờ, cảm ơn! Tôi gọi opendir() ngay trên đầu của kịch bản mong readdir() để làm thực tế, tốt, đọc. tl; dr: Hoặc gọi opendir ngay trước khi readdir hoặc sử dụng rewinddir nếu bạn mong đợi những thay đổi trong thư mục bạn đang đọc. –

Các vấn đề liên quan