مقدمة في العمل مع نظام الملفات في Rust
Rust هي لغة برمجة نظامية حديثة تركز بشكل كبير على الأمان والأداء والتحكم في الذاكرة. العمل مع نظام الملفات هو أحد المهام الأساسية التي يواجهها كل مطور. في هذه المقالة، سنشرح بالتفصيل كيفية قراءة وكتابة الملفات، إنشاء المجلدات، معالجة الأخطاء، واستخدام المكتبة القياسية std::fs للتفاعل بكفاءة مع نظام الملفات.
سنبدأ من الأساسيات ثم ننتقل تدريجياً إلى السيناريوهات الأكثر تعقيداً. جميع أمثلة الكود مكتوبة بلغة Rust وجاهزة للتشغيل. إذا كنت قد بدأت للتو في تعلم Rust، فإن هذه المقالة ستكون نقطة انطلاق ممتازة لإتقان الإدخال والإخراج (I/O) في هذه اللغة.
الوحدات والأنواع الأساسية للعمل مع نظام الملفات
في Rust، تتركز جميع وظائف العمل مع الملفات والمجلدات في الوحدة std::fs. بالإضافة إلى ذلك، تلعب الأنواع Path و PathBuf من الوحدة std::path دوراً مهماً، حيث تمثل المسارات إلى الملفات والمجلدات.
أنواع Path و PathBuf
Path هو شريحة (slice) للعمل مع المسارات دون امتلاك البيانات. PathBuf هو الإصدار المالك الذي يمكن تعديله. يوفر كلاهما طرقاً ملائمة للتعامل مع المسارات.
use std::path::Path;use std::path::PathBuf;
fn main() { // إنشاء PathBuf let mut path = PathBuf::from("/tmp"); path.push("example.txt"); println!("المسار: {}", path.display());
// التحويل إلى Path let path_ref: &Path = path.as_path(); println!("المجلد الأصلي: {:?}", path_ref.parent());}الوحدة std::fs
تحتوي الوحدة std::fs على الوظائف الأساسية للعمل مع نظام الملفات. فيما يلي الأكثر استخداماً:
read_to_string— قراءة ملف إلى نصwrite— كتابة بيانات إلى ملفcreate_dirوcreate_dir_all— إنشاء المجلداتremove_fileوremove_dir— حذف الملفات والمجلداتmetadata— الحصول على معلومات عن ملفcopyوrename— النسخ وإعادة التسمية
قراءة وكتابة الملفات في Rust
أسهل طريقة لقراءة أو كتابة ملف هي استخدام دوال التغليف التي تقوم بكل العمل في استدعاء واحد. وهي مناسبة للملفات الصغيرة التي تتسع بالكامل في الذاكرة.
قراءة ملف كامل
use std::fs;
fn main() -> Result<(), std::io::Error> { let content = fs::read_to_string("hello.txt")?; println!("محتوى الملف:{}", content); Ok(())}ترجع الدالة read_to_string قيمة Result<String>. إذا كان الملف غير موجود أو لا توجد صلاحيات للقراءة، سيتم إرجاع خطأ. لاحظ العامل ? — فهو يقوم تلقائياً بتمرير الخطأ إلى الأعلى.
الكتابة إلى ملف
use std::fs;
fn main() -> Result<(), std::io::Error> { let data = "مرحباً، Rust!"; fs::write("output.txt", data)?; println!("تمت كتابة الملف بنجاح"); Ok(())}تقوم الدالة write بإعادة كتابة الملف إذا كان موجوداً، أو إنشاء ملف جديد. لإضافة بيانات إلى نهاية الملف، استخدم OpenOptions.
العمل مع الملفات الثنائية
لقراءة وكتابة البيانات الثنائية، استخدم read و write مع متجه من البايتات:
use std::fs;
fn main() -> Result<(), std::io::Error> { // كتابة بيانات ثنائية let bytes: Vec<u8> = vec![0, 1, 2, 3, 255]; fs::write("binary.dat", &bytes)?;
// القراءة كبايتات let read_bytes = fs::read("binary.dat")?; println!("تمت قراءة