الانتقال إلى المحتوى الرئيسي
الوحدة 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 يفتح، ويقرأ كل شيء في الذاكرة ويغلق. مثالية تصل إلى بضع ميغابايت؛ أبعد من ذلك، البث هو أفضل.

فتح الملفات للتدفق

بالنسبة للملفات الكبيرة أو الوصول المتزايد، افتح الملف وأغلقه باستخدام 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)، وبرنامج إلغاء الضغط... وينطبق الشيء نفسه على io.Writer.

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]). إذا كان مفقودًا، قم بطباعة "manca argomento" ثم قم بإعادته.

جارٍ تحميل المحرر…

الحل متاح بعد 3 من المحاولات

تمرين#go.m8.l3.e2
المحاولات: 0جارٍ التحميل…

اكتب السلسلة "ciao" إلى الملف "out.txt" باستخدام os.WriteFile (الأذونات 0644). التعامل مع الخطأ.

جارٍ تحميل المحرر…

الحل متاح بعد 3 من المحاولات

Quiz#go.m8.l3.e3
جاهز

ما هو فهرس اسم البرنامج في os.Args؟

Go
fmt.Println(os.Args[???])
خيارات الإجابة