مكتبة zip لـ Rust: دليل شامل للعمل مع أرشيفات ZIP
في التطوير الحديث باستخدام Rust، يعد العمل مع الأرشيفات مهمة مطلوبة. سواء كان ذلك لتعبئة السجلات، أو فك ضغط الإعدادات، أو إنشاء النسخ الاحتياطية - فإن المكتبة القياسية zip (crate zip) هي الحل الفعلي لقراءة وكتابة ملفات ZIP. في هذه المقالة، سنشرح بالتفصيل كيفية تثبيت المكتبة، إنشاء أرشيف، استخراج الملفات، بالإضافة إلى استعراض التقنيات المتقدمة: العمل مع كلمات المرور، التدفقات، والبيانات الكبيرة.
التثبيت والإعداد
أضف التبعية في ملف Cargo.toml:
[dependencies]zip = "2.1"بعد ذلك، قم باستيراد الوحدات اللازمة في الكود:
use std::fs::File;use std::io::{Read, Write, BufReader, BufWriter};use zip::ZipWriter;use zip::write::FileOptions;use zip::read::ZipArchive;إنشاء أرشيف ZIP
لإنشاء أرشيف جديد، يتم استخدام ZipWriter. لنلق نظرة على مثال أساسي - سنقوم بتعبئة ملفين نصيين:
use std::fs::File;use std::io::Write;use zip::ZipWriter;use zip::write::FileOptions;
fn create_archive() -> 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 archive!")?;
// إضافة الملف الثاني مع الضغط let options = FileOptions::default() .compression_method(zip::CompressionMethod::Deflated) .unix_permissions(0o755); zip.start_file("data/config.json", options)?; zip.write_all(b"{\\"version\\": 1}")?;
zip.finish()?; Ok(())}هام: الطريقة start_file تفتح ملفًا جديدًا داخل الأرشيف. تسمح الخيارات بتعيين طريقة الضغط (افتراضيًا Stored - بدون ضغط، Deflated - ضغط ZIP قياسي).
قراءة واستخراج الأرشيف
للقراءة، يتم استخدام ZipArchive. فيما يلي دالة تعرض قائمة الملفات وتستخرجها إلى الدليل الحالي:
use std::fs::File;use std::io::{Read, BufReader};use zip::ZipArchive;
fn extract_archive() -> zip::result::ZipResult<()> { let file = File::open("example.zip")?; let reader = BufReader::new(file); let mut archive = ZipArchive::new(reader)?;
for i in 0..archive.len() { let mut entry = archive.by_index(i)?; let name = entry.name().to_string(); println!("جارٍ الاستخراج: {}", name);
// إنشاء ملف على القرص let mut output = File::create(&name)?; std::io::copy(&mut entry, &mut output)?; } Ok(())}الطريقة by_index تُرجع مكررًا عبر الإدخالات. إذا كنت بحاجة إلى الوصول حسب الاسم، استخدم by_name("path/to/file.txt"). لاحظ: الأسماء في ZIP قد تحتوي على مسارات بفاصل / - وهذا طبيعي للتوافق عبر المنصات.
العمل مع كلمات المرور (التشفير)
تدعم مكتبة zip التشفير المستند إلى كلمة المرور عبر خوارزمية AES (افتراضيًا AES-256). لإنشاء أرشيف مشفر:
use zip::ZipWriter;use zip::write::FileOptions;use zip::AesMode;
fn create_encrypted_archive() -> zip::result::ZipResult<()> { let file = File::create("secret.zip")?; let mut zip = ZipWriter::new(file);
let options = FileOptions::default() .compression_method(zip::CompressionMethod::Deflated) .with_aes_encryption(AesMode::Aes256, "my_strong_password");
zip.start_file("secret.txt", options)?; zip.write_all(b"Top secret data")?; zip.finish()?; Ok(())}لقراءة أرشيف مشفر، قم بتمرير كلمة المرور إلى الطريقة by_index_decrypt أو by_n