العمل مع أرشيفات ZIP في C++: نظرة عامة على المكتبات وأمثلة عملية
أرشفة البيانات هي إحدى المهام الأساسية في تطوير البرمجيات. لا يحتوي C++ على دعم مدمج لتنسيق ZIP، ومع ذلك، توجد العديد من المكتبات الناضجة والمختبرة التي تتيح بسهولة ضغط وفك ضغط وتعديل أرشيفات ZIP. في هذه المقالة، سنستعرض الأدوات الرئيسية: zlib و minizip و libzip، وسنقدم أمثلة عملية على الكود.
1. المفاهيم الأساسية للعمل مع ZIP في C++
ZIP هو تنسيق ضغط بدون فقدان يدعم عدة خوارزميات (Deflate و BZip2 و LZMA). للعمل معه في C++، تُستخدم عادةً ثلاثة أساليب:
- العمل المباشر مع zlib — ضغط/فك ضغط منخفض المستوى لتدفقات البيانات، ولكن بدون دعم بنية ملف ZIP.
- minizip — طبقة علوية فوق zlib توفر وظائف لإنشاء وقراءة أرشيفات ZIP.
- libzip — مكتبة كاملة الوظائف تدعم تحرير وحذف وإضافة الملفات إلى الأرشيفات الموجودة.
2. مكتبة zlib
zlib هي مكتبة ضغط أساسية تُبنى عليها العديد من حلول ZIP. توفر الدوال compress() و uncompress() للعمل مع البيانات الخام.
مثال: ضغط سلسلة نصية باستخدام zlib
#include <iostream>#include <string>#include <zlib.h>
int main() { std::string input = "مثال لنص للضغط في C++!"; uLong srcLen = input.size(); uLong destLen = compressBound(srcLen); char* compressed = new char[destLen]; if (compress((Bytef*)compressed, &destLen, (const Bytef*)input.data(), srcLen) == Z_OK) { std::cout << "تم الضغط: " << srcLen << " -> " << destLen << " بايت"; } delete[] compressed; return 0;}ملاحظة: للعمل مع zlib، يجب تضمين ملف الرأس zlib.h والربط مع المكتبة -lz.
3. مكتبة minizip
minizip هي غلاف خفيف الوزن فوق zlib يتيح إنشاء واستخراج أرشيفات ZIP. يتم توزيعها ضمن مصادر zlib (مجلد contrib/minizip).
مثال: إنشاء أرشيف ZIP بملف واحد
#include <iostream>#include <zip.h> // minizip
int main() { zipFile zf = zipOpen("example.zip", APPEND_STATUS_CREATE); if (!zf) { std::cerr << "خطأ في إنشاء الأرشيف"; return 1; } zip_fileinfo info = {0}; const char* filename = "test.txt"; const char* content = "مرحباً من minizip!"; if (zipOpenNewFileInZip(zf, filename, &info, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION) == ZIP_OK) { zipWriteInFileInZip(zf, content, strlen(content)); zipCloseFileInZip(zf); } zipClose(zf, nullptr); std::cout << "تم إنشاء الأرشيف: example.zip"; return 0;}مثال: استخراج جميع الملفات من ZIP
#include <iostream>#include <unzip.h>
int main() { unzFile uf = unzOpen("example.zip"); if (!uf) { std::cerr << "فشل فتح الأرشيف"; return 1; } unz_global_info global_info; unzGetGlobalInfo(uf, &global_info); for (uLong i = 0; i < global_info.number_entry; ++i) { char filename[256]; unz_file_info file_info; unzGetCurrentFileInfo(uf, &file_info, filename, sizeof(filename), nullptr, 0, nullptr, 0); if (unzOpenCurrentFile(uf) == UNZ_OK) { c