קלט/פלט

seekdir#

משחזר מטפל ספרייה למיקום שנלכד קודם לכן על־ידי telldir.

seekdir מעביר את סמן הקריאה של DIRHANDLE ל־POS, כך שקריאת readdir הבאה מחזירה את הרשומה שהייתה מוחזרת כש־POS הושג לראשונה מ־telldir על אותו מטפל. זהו בן־הזוג של ספרייה ל־seek על מטפל קובץ - עם המגבלה הקריטית ש־POS אינו offset בבייטים שניתן לחשב, הוא cookie אטום שחייב להיות נלקח מ־telldir קודם לכן.

תקציר#

seekdir DIRHANDLE, POS

מה מקבלים בחזרה#

אין ערך משמעותי. seekdir מחזיר את מה ש־seekdir(3) שמתחת מחזיר, שב־Linux הוא לא דבר שימושי - אל תסעף על ערך ההחזרה. כדי לזהות צרה, בדוק את $! לאחר הקריאה, או ודא שהמטפל עדיין פתוח לפני הקריאה.

שימוש טיפוסי#

אתה סורק ספרייה, מבחין ברשומה שאתה רוצה לבקר בה שוב מאוחר יותר, וזוכר היכן היית כדי שתוכל לחזור אליה לאחר שתמשיך לקרוא:

opendir my $dh, $path or die "opendir $path: $!";

my %bookmarks;
while (my $entry = readdir $dh) {
    $bookmarks{$entry} = telldir $dh  # position AFTER reading $entry
        if $entry =~ /\.conf\z/;
}

# later: re-read the entry that follows the first .conf file
seekdir $dh, $bookmarks{(sort keys %bookmarks)[0]};
my $next = readdir $dh;

closedir $dh;

חזרה להתחלה היא המקרה המיוחד הנפוץ - קריאת seekdir $dh, 0 שקולה ל־rewinddir על מערכות תואמות, אך rewinddir הוא האיות הניבי לכוונה זו:

seekdir $dh, 0;     # works, but say what you mean:
rewinddir $dh;      # clearer

מקרי קצה#

  • POS חייב להגיע מ־telldir על אותו מטפל. העברת מספר שלם שהמצאת, ערך ממטפל אחר, או ערך מיושן ממטפל שמאז נסגר ונפתח מחדש - היא התנהגות בלתי־מוגדרת. הקרנל עשוי לקבל אותה בשקט ולמסור לך זבל ב־readdir הבא, לדלג על רשומות, או להחזיר כפילויות.

  • הידוק־ספרייה בין telldir ל־seekdir: אם מערכת הקבצים הידקה או ארגנה מחדש את הספרייה בין שתי הקריאות (קבצים נוצרו, נמחקו או שונו־שם באותה ספרייה על־ידי תהליך כלשהו), cookie ה־POS עשוי שלא להתייחס יותר לאותה רשומה - או לרשומה כלשהי בכלל. זוהי תכונה של seekdir(3) שמתחת ואינה מגבלה של pperl. לאיטרציה יציבה על ספרייה משתנה, צלם snapshot של הרשימה עם readdir בהקשר רשימה ועבוד מהעותק.

  • מטפל לא־פתוח או סגור: קובע את $!. תחת use warnings תקבל אזהרת seekdir() attempted on invalid dirhandle. שום דבר בערך ההחזרה אינו אומר לך שזה קרה - בדוק את $! או השתמש ב־defined fileno($dh) / בקרת רישום מפורשת אם דרושה לך הגנה.

  • לא offset בבייטים: POS הוא טוקן אטום. אריתמטיקה עליו (seekdir $dh, $pos + 1) חסרת משמעות; הערכים הבטוחים היחידים הם 0 (תחילת הספרייה, וגם אז עדיף rewinddir) וערכים שהוחזרו מ־telldir.

  • סדר הרשומות לא־מצוין: seekdir משחזרת את כל סדר שהקרנל החזיר במקור. סדר זה אינו ממוין, אינו אלפביתי, ואינו מובטח להתאים ל־opendir רענן של אותו נתיב מאוחר יותר. אם הקוד שלך ממיין, מיין במפורש בכל פעם.

  • seek יחסיים בסגנון SEEK_CUR אינם קיימים למטפלי ספרייה. אין מקבילה לארגומנט whence של seek.

הבדלים מ־upstream#

תואם מלא ל־upstream Perl 5.42.

ראו גם#

  • telldir - מפיק את cookie ה־POS ש־seekdir צורך; השניים שימושיים רק כזוג

  • readdir - קורא את הרשומה הבאה; ממשיך מהמיקום ש־seekdir זה עתה קבע

  • rewinddir - הדרך הניבית לחזור לתחילת ספרייה; עדיף עליה על־פני seekdir $dh, 0

  • opendir - פותח את הספרייה ומקבל את המטפל ש־seekdir פועל עליו

  • seek - המקבילה למטפל קובץ, אך עם offset אמיתי בבייטים וארגומנט whence; למטפלי ספרייה אין אף לא אחד