דילוג לתוכן המרכזי
מודול 8 · שיעור 3 מתוך 538/50 בקורס~14 min
שיעורי מודול (3/5)

`io` ו-`os`: קבצים וזרמים

קריאה וכתיבה של קבצים וזרמים ב-Go סובבת סביב שתי חבילות משלימות: os (פתיחה, יצירה, מטא נתונים, תהליכים) וio (הממשקים Reader/Writer שמפשטים כל מקור בתים).

קריאה וכתיבה של קבצים: קיצורי הדרך

עבור קבצים קטנים או תצורה, שיחה אחת מספיקה:

Go
data, err := os.ReadFile("input.txt")        // returns []byte
if err != nil {
    return err
}
fmt.Println(string(data))

err = os.WriteFile("out.txt", []byte("ciao"), 0644)

os.ReadFile נפתח, קורא הכל לזיכרון ונסגר. מושלם עד כמה MB; מעבר לכך, הסטרימינג טוב יותר.

פתיחת קבצים להזרמה

עבור קבצים גדולים או גישה מצטברת, פתח את הקובץ וסגור אותו באמצעות defer:

Go
f, err := os.Open("big.txt")        // read-only
if err != nil {
    return err
}
defer f.Close()

buf := make([]byte, 4096)
for {
    n, err := f.Read(buf)
    if n > 0 {
        process(buf[:n])
    }
    if err == io.EOF {
        break
    }
    if err != nil {
        return err
    }
}

os.Open נפתח בקריאה בלבד. כדי לכתוב השתמש ב-os.Create (חתוך אם הוא קיים) או os.OpenFile(path, flag, perm) עם דגלים כמו os.O_APPEND | os.O_CREATE | os.O_WRONLY.

io.Reader וio.Writer: הממשקים האוניברסליים

Go
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }

בכל מקום שהספרייה הרגילה מקבלת io.Reader, אתה יכול להעביר קובץ (*os.File), מחרוזת (strings.NewReader), *bytes.Buffer, תגובת HTTP (resp.Body).

Go
// Copy from a Reader to a Writer (e.g. download → file).
n, err := io.Copy(dst, src)

io.Copy הוא סוס העבודה עבור צינורות בתים: הוא מטפל בחציצה וב-EOF בצורה נכונה. io.ReadAll(r) קורא הכל עד EOF לתוך []byte.

os.Args: ארגומנטים של CLI

os.Args הוא פרוסת מחרוזות: אינדקס 0 הוא שם התוכנית, מ-1 על הארגומנטים בפועל:

Go
func main() {
    if len(os.Args) < 2 {
        fmt.Fprintln(os.Stderr, "uso: prog <nome>")
        os.Exit(1)
    }
    fmt.Println("ciao", os.Args[1])
}

לניתוח מובנה יותר (דגלים, ברירות מחדל, עזרה) השתמש בחבילה flag מה-stdlib או ספריות חיצוניות כמו cobra.

os.Stdin, os.Stdout, os.Stderr

אלו הם שלושה *os.Files גלובליים: בכל מקום שמתקבל io.Reader או io.Writer אתה יכול לעבור אותם.

Go
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin)  // echo

תרגילים

פעילות גופנית#go.m8.l3.e1
ניסיונות: 0טוען...

הדפס את הארגומנט הראשון של שורת הפקודה (os.Args[1]). אם זה חסר, הדפיסו 'מנקה ארגומנטו' והחזירו.

טוען עורך...

הפתרון זמין לאחר 3 ניסיונות

פעילות גופנית#go.m8.l3.e2
ניסיונות: 0טוען...

כתוב את המחרוזת 'ciao' לקובץ 'out.txt' עם os.WriteFile (הרשאות 0644). טפל בשגיאה.

טוען עורך...

הפתרון זמין לאחר 3 ניסיונות

Quiz#go.m8.l3.e3
מוכן

מהו האינדקס של ה-PROGRAM NAME ב-os.Args?

Go
fmt.Println(os.Args[???])
אפשרויות תשובה