العمل مع أرشيفات ZIP في Go (Golang)
في Go (Golang)، يتم تنفيذ العمل مع أرشيفات ZIP من خلال الحزمة القياسية archive/zip. توفر هذه الحزمة جميع الأدوات اللازمة لإنشاء وقراءة وكتابة واستخراج الملفات من أرشيفات ZIP. على عكس العديد من اللغات الأخرى، لا تتطلب Go تثبيت مكتبات خارجية للعمليات الأساسية — كل شيء موجود بالفعل في المكتبة القياسية.
تدعم الحزمة archive/zip ما يلي:
- إنشاء أرشيفات ZIP جديدة
- قراءة الأرشيفات الموجودة
- إضافة الملفات والمجلدات
- استخراج ملفات فردية أو الأرشيف بأكمله
- العمل مع البيانات الوصفية للملفات (التاريخ، صلاحيات الوصول)
إنشاء أرشيف ZIP في Go
لإنشاء أرشيف، يجب فتح ملف للكتابة وإنشاء zip.Writer. يتم إضافة كل ملف عبر Create أو CreateHeader للتحكم الدقيق.
package main
import ( "archive/zip" "fmt" "io" "os")
func main() { // إنشاء ملف ZIP جديد zipFile, err := os.Create("example.zip") if err != nil { panic(err) } defer zipFile.Close()
// إنشاء Writer للأرشيف zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close()
// إضافة ملف نصي file1, err := zipWriter.Create("hello.txt") if err != nil { panic(err) } _, err = file1.Write([]byte("Hello, Go ZIP!")) if err != nil { panic(err) }
// إضافة ملف ثانٍ بمحتوى من ملف موجود sourceFile, err := os.Open("source.txt") if err != nil { panic(err) } defer sourceFile.Close()
targetFile, err := zipWriter.Create("copy_of_source.txt") if err != nil { panic(err) } _, err = io.Copy(targetFile, sourceFile) if err != nil { panic(err) }
fmt.Println("تم إنشاء الأرشيف: example.zip")}قراءة أرشيف ZIP
لقراءة الأرشيف، يُستخدم zip.OpenReader الذي يُرجع ReadCloser. يتم تمثيل كل ملف بهيكل zip.File.
package main
import ( "archive/zip" "fmt" "io" "os")
func main() { // فتح الأرشيف للقراءة reader, err := zip.OpenReader("example.zip") if err != nil { panic(err) } defer reader.Close()
// التكرار على جميع الملفات في الأرشيف for _, file := range reader.File { fmt.Printf("الملف: %s", file.Name) fmt.Printf("الحجم: %d بايت", file.UncompressedSize64) fmt.Printf("الحجم المضغوط: %d بايت", file.CompressedSize64) fmt.Printf("تاريخ التعديل: %s", file.Modified.Format("2006-01-02 15:04:05")) fmt.Println("---")
// فتح الملف من الأرشيف rc, err := file.Open() if err != nil { panic(err) } defer rc.Close()
// قراءة المحتوى (إذا كان الملف صغيراً) content, err := io.ReadAll(rc) if err != nil { panic(err) } fmt.Printf("المحتوى: %s
", string(content)) }}استخراج الملفات من الأرشيف
لفك ضغط الأرشيف بالكامل إلى مجلد، يجب إنشاء المجلدات الهدف وكتابة محتوى كل ملف.
package main
import ( "archive/zip" "fmt" "io" "os" "path/filepath")
func extractZip(src, dest string) error { reader, err := zip.OpenReader(src) if err != nil { return err } defer reader.Close()
for _, file := range reader.File { // اسم ملف آمن (منع اجتياز المسار) filePath := filepath.Join(dest, file.Name) // التحقق من عدم الخروج عن المجلد الهدف if !strings.HasPrefix(filepath.Clean(filePath),