readdir#
קריאת הרשומה הבאה, או כל הרשומות הנותרות, ממטפל ספריות שנפתח על־ידי opendir.
readdir הוא מקבילו הספרייתי של readline: הוא מושך שמות ממטפל ספריות בזה אחר זה בהקשר סקלר, או בבת־אחת בהקשר רשימה. המטפל חייב להיות כבר פתוח באמצעות opendir; האיטרציה מקדמת מיקום ש־rewinddir, seekdir, ו־telldir יכולים לתמרן.
תקציר#
readdir DIRHANDLE
my $name = readdir $dh;
my @names = readdir $dh;
while (readdir $dh) { ... } # sets $_
מה מקבלים בחזרה#
תלוי הקשר:
הקשר סקלר: שם הרשומה הבאה כמחרוזת, או
undefכאשר הספרייה מוצתה.הקשר רשימה: כל רשומה שנותרה כרשימה של מחרוזות, או הרשימה הריקה כאשר הספרייה כבר מוצתה.
הרשומות הן שמות קבצים חשופים, לא נתיבים. readdir מחזיר "foo.txt", אף פעם לא "/some/dir/foo.txt". אם מתכננים להעביר את התוצאה למבחן קובץ, open, stat, או כל קריאה אחרת שמפענחת נתיבים מול ספריית העבודה הנוכחית, הקדימו את הספרייה בעצמכם - readdir אינו מבצע chdir לספרייה שאותה הוא קורא.
הרשימה תמיד כוללת את הרשומות . (הספרייה הנוכחית) ו־.. (ספריית האב) כפי שמדווחות על־ידי מערכת הקבצים הבסיסית. סננו אותן במפורש אם אינכם רוצים אותן:
my @real = grep { $_ ne '.' && $_ ne '..' } readdir $dh;
הסדר תלוי במערכת הקבצים, ולא אלפביתי. ext4, XFS, tmpfs, NFS, ו־FAT, כל אחת מחזירה רשומות בסדר הפנימי שלה, שיכול להיות סדר הכנסה, סדר האש, או משהו אחר לגמרי. לעולם אל תניחו פלט ממוין. אם נחוץ סדר צפוי, מיינו את התוצאה:
my @names = sort readdir $dh;
דוגמאות#
קריאת כל שם לרשימה, השלכת רשומות הנקודות, ומיון:
opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
my @names = sort grep { !/^\.\.?\z/ } readdir $dh;
closedir $dh;
איטרציה רשומה אחת בכל פעם. readdir חשוף בתנאי while מציב ל־$_ ובודק את התוצאה למוגדרוּת, לא לאמיתיוּת - כך שרשומה ששמה מילולית "0" עדיין שומרת את הלולאה רצה:
opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
while (readdir $dh) {
print "$some_dir/$_\n";
}
closedir $dh;
מבחן קובץ עם הספרייה מקודמת - שכחת הקידומת היא הבאג הקלאסי של readdir:
opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
my @dotfiles = grep { /^\./ && -f "$some_dir/$_" } readdir $dh;
closedir $dh;
הקשר סקלר - שם אחד לכל קריאה, undef מסמן סוף ספרייה:
opendir(my $dh, $some_dir) or die "opendir $some_dir: $!";
while (defined(my $name = readdir $dh)) {
next if $name eq '.' || $name eq '..';
process("$some_dir/$name");
}
closedir $dh;
חזרה לאחור וקריאה בפעם השנייה - המטפל נשאר פתוח וניתן לשימוש:
my @first = readdir $dh;
rewinddir $dh;
my @second = readdir $dh; # same entries, possibly different order
מקרי קצה#
מטפל מוצה: קריאות נוספות מחזירות
undefבהקשר סקלר, רשימה ריקה בהקשר רשימה. השתמשו ב־rewinddirכדי להתחיל מחדש.מטפל סגור או לא־תקף: מחזיר
undef(סקלר) או רשימה ריקה (רשימה) ומגדיר את$!. תחתuse warnings, Perl פולטreaddir() attempted on invalid dirhandle.מבחן מוגדרוּת ב־
while: גםwhile (readdir $dh)וגםwhile (my $n = readdir $dh)(ומקבילותיהם ב־for) מטופלים במיוחד לבחינתdefined, לא אמיתיוּת. רשומה ששמה"0"מוחזרת והלולאה ממשיכה..ו־..נוכחים תמיד במערכות קבצים POSIX, גם בספרייה ריקה לחלוטין אחרת. סננו אותם אם רוצים רק תוכן אמיתי.ללא קידומת נתיב: הרשומות הן שמות חשופים. כל מבחן קובץ או
openעל ערך ההחזרה הגולמי בודק יחסית לספריית העבודה הנוכחית, לא$some_dir.אין מיון: הסדר הוא מה שהקרנל מחזיר. החילו
sortבמפורש אם יציבות חשובה.שינויי ספרייה במקביל: רשומות שמתווספות או מוסרות במהלך איטרציה עשויות להופיע או שלא, לפי הפלטפורמה. ההנחה הבטוחה היחידה היא שרשומות שנוכחו בעת
opendirולא הוסרו ידווחו.קידוד:
readdirמחזיר מחרוזות בתים כפי שהקרנל מאחסן אותם. במערכת קבצים שמשתמשת בשמות קבצים UTF-8, החילוEncode::decode_utf8או הגדירו את הפרגמהopenאם נחוצות מחרוזות תווים.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
opendir- פותח את מטפל הספריות ש־readdirקורא ממנו; תמיד הקריאה הראשונה ברצףclosedir- משחרר את המטפל לאחר שהאיטרציה הסתיימהrewinddir- מאפס את מיקום האיטרציה להתחלת הספרייהseekdir- קופץ למיקום שנרשם קודם לכןglob- התאמת תבניות בסגנון shell על תוכן ספרייה; גבוה־רמה יותר כשרוצים*.txtבמקום כל רשומה