קלט/פלט

eof#

בודק מטפל קובץ עבור סוף־קובץ.

eof מדווח האם הקריאה הבאה על מטפל קובץ תחזיר סוף־קובץ. שלוש צורות הקריאה נראות דומות אך משמעותן שונה: eof FILEHANDLE שואל על מטפל ספציפי, eof חשוף שואל על המטפל שממנו קראו לאחרונה, ו־eof() עם סוגריים ריקים שואל על זרם ARGV הווירטואלי המוזן על־ידי <>. הצורות אינן ניתנות להחלפה - בחירת הצורה הלא־נכונה היא הבאג הקלאסי של built-in זה.

תקציר#

eof FILEHANDLE
eof()
eof

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

1 אם הקריאה הבאה על המטפל תחזיר סוף־קובץ, או אם המטפל אינו פתוח. 0 אחרת. eof לעולם אינו חוסם בהמתנה לקלט נוסף בקובץ רגיל, אך ב־pipe או טרמינל הוא עשוי לקרוא ולהחזיר תו אחד כדי להחליט - ראה מקרי קצה.

מצב גלובלי שהוא נוגע בו#

  • ARGV - מטפל הקובץ הקסום העומד מאחורי האופרטור <>. eof() בוחן ועשוי לקדם אותו; eof בתוך לולאת while (<>) מתשאל אותו בעקיפין.

  • @ARGV - רשימת שמות הקבצים ש־<> עובר עליהם. eof() שנקרא לפני שנעשה שימוש ב־<> מפעיל בחינה של @ARGV, ואם ריק, מארגן את STDIN להיקרא.

  • $. - מספר שורת הקלט הנוכחית, מצורף למטפל ש־eof מתשאל. אינו נכתב על־ידי eof עצמו, אך רלוונטי באידיומים שלהלן שבהם close ARGV מאפס אותו בגבולות הקובץ.

שלוש הצורות, מפורטות#

eof FILEHANDLE - שואל על המטפל הזה האחד. FILEHANDLE יכול להיות bareword, סקלר המחזיק מטפל, או ביטוי המוערך לאחד. מחזיר אמת עבור מטפל סגור או שמעולם לא נפתח.

eof (ללא סוגריים, ללא ארגומנט) - שואל על הקובץ האחרון שנקרא. בתוך לולאת while (<>) { ... } משמעו ״קובץ ה־ARGV הנוכחי״ - הקובץ הפיזי המוזרם כעת, לא כל רצף ה־<>. eof הופך לאמת בכל גבול קובץ, פעם אחת לכל קובץ קלט.

eof() (סוגריים ריקים) - שואל על זרם ה־<> בכללותו. הוא הופך לאמת רק בסוף הקובץ האחרון ב־@ARGV. אם <> עוד לא נעשה בו שימוש, eof() יבחן את @ARGV, יחזור ל־STDIN כאשר @ARGV ריק, ועשוי למעשה לפתוח את הקובץ הראשון כדי לענות על השאלה.

eof חשוף ו־eof() נראים כמעט זהים ועושים דברים שונים לגמרי. הסוגריים חשובים.

דוגמאות#

בדוק מטפל ספציפי לפני הקריאה הבאה:

open my $fh, "<", "data.txt" or die $!;
while (not eof $fh) {
    my $line = <$fh>;
    # process $line
}
close $fh;

האידיום הקלאסי while (<>), איפוס $. בכל גבול קובץ. eof חשוף (ללא סוגריים) הוא מה שאתה רוצה כאן - הוא מופעל פעם לכל קובץ קלט:

while (<>) {
    next if /^\s*#/;
    print "$.\t$_";
} continue {
    close ARGV if eof;        # not eof() - resets $. per file
}

הוסף סמן לפני השורה האחרונה של הקובץ האחרון. eof() עם סוגריים תופס את סוף כל זרם ה־<>, לא של כל קובץ:

while (<>) {
    if (eof()) {
        print "--------------\n";
    }
    print;
    last if eof();            # needed when reading from a terminal
}

התגונן מפני מטפל סגור. eof על מטפל סגור או שמעולם לא נפתח מחזיר אמת ללא אזהרה:

my $fh;                       # never opened
if (eof $fh) {
    warn "handle not ready";
}

מקרי קצה#

  • eof לפני כל קריאה מחזיר שקר, לא אמת. ל־eof חשוף ללא קריאה קודמת אין ״קובץ אחרון שנקרא״ להתייחס אליו ו־Perl מתייחס אליו כשקר. כתיבת if (eof) { ... } בראש תוכנית אינה אומרת ״אם אין קלט״ - השתמש ב־eof() לכך.

  • ל־eof() לפני שנעשה שימוש ב־<> יש תופעות לוואי. הוא בוחן את @ARGV, ואם @ARGV ריק הוא מארגן ש־<> יקרא מ־STDIN. eof() תועה בתחילת התוכנית יכול לפיכך לקשור בשקט את התוכנית ל־STDIN.

  • eof() לאחר ש־<> מיצה את הקלט שלו מניח שאתה מתחיל מעבר @ARGV נוסף. אם @ARGV ריק בנקודה זו, ה־<> הבא קורא מ־STDIN. בדרך כלל זה לא מה שאתה רוצה; קבע את @ARGV במפורש או בדוק את צורת eof החשוף במקום.

  • eof בטרמינל צורך תו. המימוש קורא בית אחד ומבצע ungetc כדי לדעת האם קיים קלט נוסף. בטרמינלים ההחזרה עשויה שלא לשרוד לאחר שהושג סוף־קובץ - אל תקרא eof FH בטרמינל לאחר שכבר הגעת לשם ל־EOF, או שהמטפל יכול לאבד את תנאי סוף־הקובץ שלו.

  • מטפל סגור או שמעולם לא נפתח - eof FILEHANDLE מחזיר אמת. אין דרך להבחין בין ״סגור״ ל־״ב־EOF״ באמצעות eof לבד; בדוק fileno או עקוב אחר מצב הפתיחה בעצמך אם זה משנה.

  • eof(ARGV) שווה ל־eof חשוף בתוך while (<>). שניהם מתשאלים את קובץ ה־ARGV הנוכחי. העדף eof חשוף לקיצור וכדי להבחין ויזואלית בצורת eof() הסוגרת.

  • אתה לעיתים נדירות זקוק ל־eof בכלל. אופרטורי הקלט מחזירים undef בסוף־קובץ, כך ש־while (my $line = <$fh>) { ... } ו־while (<>) { ... } מטפלים בסיום ללא כל בדיקת eof. פנה ל־eof רק כאשר אתה צריך לפעול בגבול - שורה אחרונה, איפוס פר־קובץ, סמן קובץ אחרון.

הבדלים מ־upstream#

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

ראו גם#

  • readline - קרא שורה ממטפל; מחזיר undef בסוף־קובץ, מה שמחליף את רוב השימושים ב־eof

  • read - קריאת בלוק של ספירת בתים קבועה; מחזיר 0 בסוף־קובץ

  • getc - קרא תו יחיד; מחזיר undef בסוף־קובץ

  • close - סגור מטפל; השותף הנפוץ של eof באידיום close ARGV if eof לאיפוס פר־קובץ

  • ARGV - המטפל הקסום המוזן על־ידי <> ש־eof ו־eof() מתשאלים