العمل مع أرشيفات ZIP في Go: دليل شامل لحزمة archive/zip

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

العمل مع أرشيفات ZIP في Go (Golang)



في التطوير الحديث بلغة Go، غالبًا ما تنشأ الحاجة للعمل مع الأرشيفات — لتغليف السجلات، نشر الإعدادات، النسخ الاحتياطية أو نقل البيانات بين الخدمات المصغرة. توفر المكتبة القياسية للغة Go حزمة قوية ومرنة archive/zip، والتي تسمح بإنشاء وقراءة وتعديل أرشيفات ZIP دون تبعيات خارجية. في هذه المقالة، سنشرح بالتفصيل جميع جوانب العمل مع أرشيفات ZIP في Go.



نظرة عامة على حزمة archive/zip



حزمة archive/zip مضمنة في المكتبة القياسية للغة Go وتدعم:

  • قراءة وكتابة أرشيفات ZIP (تنسيق PKWARE)
  • الضغط بطريقة Deflate و Stored (بدون ضغط)
  • العمل مع الملفات والمجلدات داخل الأرشيف
  • دعم التعليقات للأرشيف والملفات الفردية
  • تعيين سمات الملفات (التاريخ، صلاحيات الوصول)
  • المعالجة التدفقية (يمكن أن تزن الأرشيفات غيغابايتات)


الأنواع الرئيسية: zip.Writer لإنشاء الأرشيفات و zip.Reader للقراءة.



إنشاء أرشيف ZIP



لإنشاء أرشيف، يُستخدم zip.NewWriter الذي يستقبل io.Writer. يتم إضافة كل ملف عبر Create أو CreateHeader.



package main

import ( "archive/zip" "bytes" "fmt" "io" "log" "os")

func main() { // إنشاء مخزن مؤقت للأرشيف buf := new(bytes.Buffer) writer := zip.NewWriter(buf)

// إضافة ملف نصي file1, err := writer.Create("hello.txt") if err != nil { log.Fatal(err) } _, err = file1.Write([]byte("Hello, Go ZIP!")) if err != nil { log.Fatal(err) }

// إضافة ملف مع مجلد فرعي file2, err := writer.Create("config/settings.json") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte(`{"version": 1, "debug": true}`)) if err != nil { log.Fatal(err) }

// إغلاق الكاتب إلزاميًا err = writer.Close() if err != nil { log.Fatal(err) }

// حفظ الأرشيف على القرص err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("تم إنشاء الأرشيف: example.zip")}


قراءة واستخراج الملفات من الأرشيف



لقراءة الأرشيف، يُستخدم zip.NewReader الذي يُمرر إليه io.ReaderAt وحجم الأرشيف. يمكن القراءة في الذاكرة أو بشكل تدفقي.



func readArchive() {    // فتح ملف الأرشيف    reader, err := zip.OpenReader("example.zip")    if err != nil {        log.Fatal(err)    }    defer reader.Close()

// التكرار عبر جميع الملفات في الأرشيف for _, file := range reader.File { fmt.Printf("الملف: %s (الحجم: %d بايت)", file.Name, file.UncompressedSize64)

// فتح الملف داخل الأرشيف rc, err := file.Open() if err != nil { log.Fatal(err) }

// قراءة المحتوى content, err := io.ReadAll(rc) if err != nil { log.Fatal(err) } rc.Close()

fmt.Printf("المحتوى: %s

", content) }}


إضافة ملفات مع بيانات وصفية



باستخدام zip.FileHeader يمكن تعيين التاريخ، صلاحيات الوصول وطريقة الضغط:



func addFileWithMetadata(w *zip.Writer, name, content string) error {    header := &zip.FileHeader{        Name:   name,        Method: zip.Deflate, // استخدام Deflate (ضغط)    }    // تعيين وقت التعديل    header.SetModTime(time.Now())    // تعيين صلاحيات الوصول (Unix rw-r--r--)    header.SetMode(0644)

f, err := w.CreateHeader(header) if err != nil { return err } _, err = f.Write([]byte(content)) return

توصيات