Rust والملفات: من المبتدئ إلى المحترف في التعامل مع نظام الملفات

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

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

ابدأ الدورة

لماذا العمل مع الملفات في Rust ليس ألماً، بل متعة؟

\n\n

إذا كنت معتاداً على Python، حيث open() يحل كل شيء تقريباً، قد يبدو Rust كمعلم صارم. لكن خلف هذه الصرامة تكمن قوة لا تصدق. Rust لن يسمح لك بترك ملف مفتوحاً عن طريق الخطأ، أو قراءة البايتات كسلسلة نصية، أو نسيان التحقق من وجود دليل. في هذه المقالة، سنشرح العمل مع الملفات ونظام الملفات في Rust - من العمليات البسيطة إلى التقنيات المتقدمة. ستتعلم كيفية القراءة، الكتابة، الإنشاء، والحذف للملفات، وكذلك كيفية إدارة المسارات بفعالية.

\n\n

هل أنت مستعد؟ هيا بنا!

\n\n

الأساسيات: فتح، قراءة، إغلاق

\n\n

في Rust لا توجد دالة مدمجة open() كما في Python. بدلاً من ذلك، نستخدم الوحدة القوية std::fs. لنبدأ بأبسط شيء - قراءة ملف كامل.

\n\n

قراءة ملف كامل إلى سلسلة نصية

\n\n

أبسط طريقة لقراءة ملف هي استخدام std::fs::read_to_string. هذا مشابه لـ file.read() في Python، ولكن مع ضمان الأمان.

\n\n
use std::fs;\n\nfn main() {\n    let content = fs::read_to_string("hello.txt")\n        .expect("لم يتمكن من قراءة الملف");\n    println!("محتوى الملف:\\n{}", content);\n}
\n\n

لاحظ .expect(). في Rust لا توجد استثناءات - يوجد Result. إذا لم يكن الملف موجوداً، سيتعطل البرنامج مع رسالة مفهومة. للكود الإنتاجي، من الأفضل استخدام match أو unwrap_or_else، ولكن للتعلم، expect مثالي.

\n\n

الكتابة في ملف

\n\n

الكتابة بديهية أيضاً:

\n\n
use std::fs;\n\nfn main() {\n    let data = "Hello, Rust!\\nهذه كتابة اختبارية.";\n    fs::write("output.txt", data)\n        .expect("لم يتمكن من كتابة الملف");\n    println!("تم كتابة الملف بنجاح!");\n}
\n\n

الطريقة fs::write تنشئ الملف إذا لم يكن موجوداً، وتستبدل المحتوى إذا كان الملف موجوداً. لإضافة بيانات إلى نهاية الملف، استخدم OpenOptions.

\n\n

العمل مع المسارات: Path و PathBuf

\n\n

في Rust هناك نوعان رئيسيان للعمل مع المسارات: Path (مستعار، غير قابل للتغيير) و PathBuf (خاص، قابل للتغيير). فهم الفرق بينهما هو مفتاح العمل الفعال مع نظام الملفات.

\n\n

إنشاء ومعالجة المسارات

\n\n
use std::path::{Path, PathBuf};\n\nfn main() {\n    // إنشاء مسار\n    let path = Path::new("data/subdir/file.txt");\n    \n    // الحصول على مكونات المسار\n    println!("الدليل الأب: {:?}", path.parent());\n    println!("اسم الملف: {:?}", path.file_name());\n    println!("الامتداد: {:?}", path.extension());\n    \n    // تجميع مسار جديد\n    let mut new_path = PathBuf::from("backup");\n    new_path.push("data");\n    new_path.push("file.txt");\n    println!("المسار الجديد: {}", new_path.display());\n}
\n\n

الطريقة .display() إلزامية إذا كنت تريد طباعة المسار في الطرفية. Rust لا يسمح بإدراج المسار مباشرة في سلسلة نصية - هذه حماية من مشاكل الترميز.

\n\n

القراءة والكتابة: المستوى المتقدم

\n\n

عندما تحتاج إلى تحكم أكبر، استخدم File و BufReader/BufWriter.

\n\n

قراءة ملف سطراً سطراً

\n\n

للملفات الكبيرة، قراءة كل شيء في الذاكرة غير فعالة. استخدم القراءة المخزنة:

\n\n
use std::fs::File;\nuse std::io::{BufRead, BufReader};\n\nfn main() {\n    let file = File::open("large_file.txt")\n        .expect("الملف غير موجود");\n    let reader = BufReader::new(file);\n    \n    for (index, line) in reader.lines().enumerate() {\n        let line = line.expect("خطأ في قراءة السطر");\n        println!("السطر {}: {}", index + 1, line);\n    }\n}
\n\n

هذا الأسلوب يسمح بمعالجة الملفات من أي حجم، دون تحميلها بالكامل في الذاكرة العاملة.

\n\n

إضافة بيانات إلى نهاية الملف

\n\n

المدونات

توصيات الكتب