מטפלי קובץ קבצים ספריות

open#

משייך מטפל קובץ לקובץ, לפקודה, או לסקלר בזיכרון.

open היא הדרך הראשית שבה תוכנית Perl רוכשת מטפל קובץ. צורת שלושת־הארגומנטים - open $fh, MODE, EXPR - היא זו שיש להשתמש בה בקוד חדש: המצב מצוין במפורש, שם הקובץ אינו יכול להתפרש מחדש כשרשרת shell, ורווחים מובילים או נגררים ב־EXPR נשמרים מילולית. צורת שני־הארגומנטים הישנה יותר קיימת לתאימות ולפירוש שם הקובץ ה״קסום״ שהיא מאפשרת; אל תזינו לה קלט בלתי־מהימן.

תקציר#

open my $fh, "<",  $path           or die "read $path: $!";
open my $fh, ">",  $path           or die "write $path: $!";
open my $fh, ">>", $path           or die "append $path: $!";
open my $fh, "+<", $path           or die "rw $path: $!";
open my $fh, "<:encoding(UTF-8)", $path or die $!;
open my $mem, ">",  \$buf          or die $!;   # in-memory
open my $pipe, "-|", "ls", "-la"   or die $!;   # read from cmd
open my $pipe, "|-", "gzip", ">$f" or die $!;   # write to cmd

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

1 בהצלחה; undef בכשל, עם $! מוגדר לשגיאת ה־OS. עבור צורות ה־pipe (|- / -|), ערך ההחזרה בהצלחה הוא ה־pid של תהליך הילד - שימושי כשצריך לעשות waitpid עליו מאוחר יותר. לאחר open של pipe עם ארגומנט אחד או שניים על הפקודה המילולית -, open מחזיר פעמיים (ההורה מקבל את ה־pid של הילד, הילד מקבל 0); השתמשו ב־defined($pid) או // כדי להבחין בין השניים.

בדקו תמיד את ערך ההחזרה. open כושל משאיר את מטפל הקובץ סגור, וכל קריאה או כתיבה לאחר מכן עליו תקבע את $! ל־Bad file descriptor ותפיק אזהרה תחת use warnings.

open my $fh, "<", $path
    or die "open $path: $!";

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

  • $! - נקבע בכשל לשגיאה ברמת ה־OS.

  • ${^OPEN} - שכבות I/O ברירת מחדל המותקנות על־ידי הפראגמה open או המתג -CioD. אלה חלות רק כאשר MODE בצורת שלושת־הארגומנטים אינו מכיל שכבה מפורשת; < או > עירומים מכבדים אותן, <:raw או כל שכבה מפורשת אחרת מדכאת אותן.

  • $^F - ה־file descriptor הגבוה ביותר שאינו מסומן close-on-exec; ה־fd החדש יורש את דגל close-on-exec בהתבסס על זה.

  • מטפל קובץ נבחר דרך select - אינו משתנה על־ידי open, אך הופך לרלוונטי ברגע ש־print למטפל החדש מבלי לנקוב בשמו.

  • עבור צורות pipe, $? ו־${^CHILD_ERROR_NATIVE} נקבעים כאשר המטפל נסגר מאוחר יותר.

מצבים#

הארגומנט השני נוקב בתפקיד I/O. המקרים הנפוצים:

מצב

משמעות

מקבילה ב־fopen(3)

<

קריאה

r

>

כתיבה, חיתוך או יצירה

w

>>

הוספה בסוף, יצירה אם חסר

a

+<

קריאה וכתיבה, ללא חיתוך

r+

+>

קריאה וכתיבה, חיתוך תחילה

w+

|-

pipe לפקודה (אנחנו כותבים)

-

-|

pipe מפקודה (אנחנו קוראים)

-

<&, >&, <&=, >&=

dup או fdopen על מטפל קיים

-

קבצים חדשים שנוצרו מקבלים הרשאות 0666 & ~umask. +< הוא כמעט תמיד מה שרוצים לקריאה־כתיבה; +> דורס את הקובץ תחילה.

שכבות I/O מתחברות לאחר המצב: <:encoding(UTF-8), >:raw, >>:crlf, <:encoding(UTF-8):crlf. שכבה מפורשת מדכאת את ברירות המחדל של ${^OPEN}; נקודתיים בודדות (<:) חוזרות לברירת המחדל של ה־OS (:raw ב־Unix, :crlf ב־Windows).

דוגמאות#

קריאת קובץ טקסט UTF-8 שורה אחר שורה:

open my $fh, "<:encoding(UTF-8)", "notes.txt"
    or die "open notes.txt: $!";
while (my $line = <$fh>) {
    chomp $line;
    # ... use $line ...
}
close $fh or warn "close: $!";

כתיבת קובץ בינארי ללא תרגום קידוד:

open my $out, ">:raw", "image.bin"
    or die "open image.bin: $!";
print $out $bytes;
close $out or die "close: $!";

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

my $buf = "";
open my $mem, ">", \$buf or die $!;
print $mem "hello\n";
close $mem;
# $buf now contains "hello\n"

קריאה מפקודה, בצורת רשימה כך שהארגומנטים אינם כפופים לפירוש מטה־תווים של ה־shell:

open my $ls, "-|", "ls", "-la", $dir
    or die "ls: $!";
while (<$ls>) { print }
close $ls;                     # $? holds the exit status

קובץ אנונימי זמני - העבירו undef כארגומנט השלישי עם מצב קריאה־כתיבה, ואז seek חזרה להתחלה כדי לקרוא את מה שכתבתם:

open my $tmp, "+>", undef or die $!;
print $tmp "scratch data\n";
seek $tmp, 0, 0;
my $line = <$tmp>;

מקרי קצה#

  • open ״קסום״ בשני־ארגומנטים: open $fh, $name מכבד <, >, >> מובילים, | נגרר, ומסיר רווחים סובבים מ־$name. בסדר עבור שם קובץ מילולי שהקלדתם בעצמכם; לעולם לא עבור שם קובץ שהגיע מקלט משתמש, מהרשת, או ממשתנה סביבה. השתמשו בצורת שלושת־הארגומנטים.

  • - בשני־ארגומנטים: open $fh, "<-" או open $fh, "-" פותח את STDIN; open $fh, ">-" פותח את STDOUT. המקבילות בשלושה־ארגומנטים הן open $fh, "<", "-" ו־open $fh, ">", "-".

  • פתיחה מחדש של STDOUT / STDERR: סגרו אותם תחילה, ואז פתחו מחדש מול היעד החדש. open STDOUT, ">", \$buf מנתב את כל הפלט הבא של print STDOUT לתוך $buf.

  • מטפלי קובץ כ־Bareword (open FH, ...) הם גלובלים של חבילה והם מושבתים תחת use v5.36 ואילך באמצעות התכונה bareword_filehandles. העדיפו סקלר לקסיקלי.

  • שכבות ו־${^OPEN}: כל שכבה מפורשת, אפילו :, משביתה את ברירות המחדל מהפראגמה open. אם אתם מסתמכים על ברירת מחדל של פראגמה, השמיטו את הנקודתיים לחלוטין (<, לא <:).

  • Pipe לפקודה עם מטה־תווים של shell: צורת ה־pipe בשני־ארגומנטים (open $fh, "|cat -n | lpr") רצה דרך /bin/sh -c. צורת הרשימה בשלושה־ארגומנטים (open $fh, "|-", "cat", "-n") אינה, והיא ברירת המחדל הבטוחה יותר.

  • מחרוזות סקלר בזיכרון: מטופלות כמחרוזות אוקטטים. ללא חיתוך, הסקלר אינו יכול להכיל נקודות קוד מעל 0xFF.

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

  • open מול sysopen: open עוטף את הסמנטיקה של fopen(3) עם שכבות PerlIO מעליה. עבור דגלי open(2) ישירים כמו O_EXCL או O_NOFOLLOW, השתמשו ב־sysopen.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • close - שחרור מטפל קובץ; בדקו את ערך ההחזרה שלו עבור כתיבות שעברו בופרינג ופקודות pipe

  • sysopen - פתיחה עם דגלי open(2) גולמיים כשצריך O_EXCL, O_NOFOLLOW, או דיוק דומה

  • binmode - דחיפת או החלפת שכבות I/O על מטפל שכבר פתוח

  • read - קריאות בייט בגודל קבוע מהמטפל ש־open החזיר

  • readline - קריאות רשומה־בכל־פעם (מה ש־<$fh> קורא)

  • fileno - ה־file descriptor הבסיסי של ה־OS, עבור flock, select, או fcntl

  • $! - שגיאת OS שנקבעת כאשר open מחזיר undef