دروس الوحدة (3/5)
`io` و`os`: الملفات والتدفقات
تتمحور قراءة وكتابة الملفات والتدفقات في Go حول حزمتين متكاملتين: os (الفتح والإنشاء والبيانات الوصفية والعمليات) وio (الواجهات Reader/Writer التي تلخص أي مصدر بايت).
قراءة وكتابة الملفات: الاختصارات
بالنسبة للملفات الصغيرة أو ملفات التكوين، يكفي إجراء مكالمة واحدة:
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:
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: الواجهات العامة
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.
// 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 في الوسائط الفعلية:
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، يمكنك تجاوزها.
fmt.Fprintln(os.Stderr, "log diagnostico")
io.Copy(os.Stdout, os.Stdin) // echoتمارين
اطبع وسيطة سطر الأوامر الأولى (os.Args[1]). إذا كان مفقودًا، قم بطباعة "manca argomento" ثم قم بإعادته.
الحل متاح بعد 3 من المحاولات
اكتب السلسلة "ciao" إلى الملف "out.txt" باستخدام os.WriteFile (الأذونات 0644). التعامل مع الخطأ.
الحل متاح بعد 3 من المحاولات
ما هو فهرس اسم البرنامج في os.Args؟
fmt.Println(os.Args[???])