مكتبة zip للعمل مع الأرشيفات في Rust
في التطوير الحديث باستخدام Rust، غالبًا ما تنشأ الحاجة إلى ضغط البيانات في أرشيفات ZIP أو استخراجها منها. سواء كان الأمر يتعلق بإنشاء نسخ احتياطية، أو توزيع البرامج، أو معالجة ملفات المستخدمين - فإن مكتبة zip هي الحل القياسي لهذه المهمة. توفر واجهة برمجة تطبيقات (API) مريحة لقراءة وكتابة وتعديل أرشيفات ZIP، مع دعم كل من المعالجة التدفقية والعمل في الذاكرة.
التثبيت والإعداد
للبدء، أضف التبعية إلى ملف Cargo.toml الخاص بك:
[dependencies]zip = "2.1"قد تحتاج أيضًا إلى crate std::io للعمل مع تدفقات البيانات، وهو مضمن بالفعل في المكتبة القياسية لـ Rust.
إنشاء أرشيف ZIP جديد
لنلقِ نظرة على أبسط مثال - إنشاء أرشيف يحتوي على ملف نصي واحد. يتم استخدام ZipWriter لهذا الغرض، والذي يغلف أي نوع يقوم بتنفيذ Write:
use std::fs::File;use std::io::Write;use zip::write::FileOptions;use zip::ZipWriter;
fn main() -> zip::result::ZipResult<()> { let file = File::create("example.zip")?; let mut zip = ZipWriter::new(file);
zip.start_file("hello.txt", FileOptions::default())?; zip.write_all(b"Hello, Rust ZIP!")?;
zip.finish()?; Ok(())}لاحظ طريقة start_file - فهي تبدأ كتابة ملف جديد داخل الأرشيف. يمكنك تمرير خيارات الضغط وتاريخ التعديل ومعلمات أخرى إليها.
قراءة واستخراج الملفات
لقراءة الأرشيف، يتم استخدام ZipArchive. يتيح لك التكرار عبر جميع الإدخالات واستخراج محتوياتها:
use std::fs::File;use std::io::Read;use zip::ZipArchive;
fn main() -> zip::result::ZipResult<()> { let file = File::open("example.zip")?; let mut archive = ZipArchive::new(file)?;
for i in 0..archive.len() { let mut entry = archive.by_index(i)?; let name = entry.name().to_string(); let mut content = String::new(); entry.read_to_string(&mut content)?; println!("{}: {}", name, content); } Ok(())}طريقة by_index تُرجع إدخالاً محددًا حسب الفهرس. كما يتوفر البحث بالاسم عبر by_name، لكن ضع في اعتبارك أن الأسماء في ZIP قد تكون بترميزات مختلفة.
إضافة ملفات إلى أرشيف موجود
تدعم مكتبة zip أيضًا إضافة ملفات جديدة إلى أرشيف تم إنشاؤه بالفعل. يتم ذلك باستخدام طريقة raw_copy_file أو عن طريق فتح الأرشيف في وضع الإضافة:
use std::fs::File;use std::io::Write;use zip::write::FileOptions;use zip::ZipWriter;
fn append_to_zip() -> zip::result::ZipResult<()> { let file = File::options() .read(true) .write(true) .open("example.zip")?; let mut zip = ZipWriter::new_append(file)?;
zip.start_file("new_file.txt", FileOptions::default())?; zip.write_all(b"Added later!")?;
zip.finish()?; Ok(())}هام: لإضافة ملف، يجب فتح الأرشيف مع صلاحيات القراءة والكتابة، ويجب ألا يكون الملف نفسه تالفًا.
العمل مع أنواع مختلفة من الضغط
بشكل افتراضي، تستخدم المكتبة طريقة Deflated (الضغط القياسي لـ ZIP). يمكنك تغييرها إلى Stored (بدون ضغط) أو طرق أخرى عن طريق تمرير الخيارات المناسبة:
use zip::CompressionMethod;use zip::write::FileOptions;
let options = FileOptions::default() .compression_method(CompressionMethod::Stored);// أوlet options = FileOptions::default() .compression_method(CompressionMethod::Deflated);إذا كنت بحاجة إلى أقصى ضغط، حدد المستوى:
<