العمل مع نظام الملفات في لغة Rust: دليل شامل
تُعد لغة Rust لغة برمجة أنظمة حديثة تقدم أدوات قوية وآمنة للعمل مع نظام الملفات. بفضل نظام الأنواع الصارم ونموذج الملكية، تساعد Rust في تجنب العديد من الأخطاء المتعلقة بإدارة الملفات، مثل تسابق البيانات أو تسرب الموارد. في هذه المقالة، سندرس بدقة كيفية تنفيذ عمليات نظام الملفات الأساسية في Rust: إنشاء وقراءة وكتابة ونسخ وحذف الملفات والمجلدات. جميع أمثلة الأكواد مكتوبة باستخدام المكتبة القياسية std::fs.
إعداد المشروع واستيراد الوحدات
للبدء، قم بإنشاء مشروع جديد باستخدام Cargo:
cargo new file_system_democd file_system_demoافتح الملف src/main.rs وأضف الواردات التالية:
use std::fs;use std::io::{self, Write, Read};use std::path::Path;توفر الوحدة std::fs دوالاً للعمل مع الملفات والمجلدات. تحتوي std::io على سمات (traits) للإدخال/الإخراج، بينما تُستخدم std::path::Path للعمل مع المسارات.
إنشاء وكتابة الملفات
أبسط طريقة لإنشاء ملف وكتابة بيانات إليه هي استخدام الدالة fs::write. تأخذ هذه الدالة مسار الملف والمحتوى كبايتات أو كسلسلة نصية.
fn main() -> io::Result<()> { // إنشاء ملف وكتابة سلسلة نصية إليه fs::write("hello.txt", "Hello, Rust!")?; println!("تم إنشاء الملف بنجاح."); Ok(())}إذا كنت بحاجة إلى تحكم أكبر، استخدم fs::File والطرق write أو write_all:
fn main() -> io::Result<()> { let mut file = fs::File::create("data.txt")?; file.write_all(b"Data string")?; file.write_all("Another string".as_bytes())?; Ok(())}لاحظ العلامة ? — هذا هو عامل نشر الخطأ. إذا فشلت العملية، سيتم إرجاع الخطأ من الدالة.
قراءة الملفات
لقراءة المحتوى الكامل لملف في سلسلة نصية، استخدم fs::read_to_string:
fn main() -> io::Result<()> { let contents = fs::read_to_string("hello.txt")?; println!("محتوى الملف:{}", contents); Ok(())}إذا كان الملف يحتوي على بيانات ثنائية، استخدم fs::read، والتي تُرجع Vec<u8>:
fn main() -> io::Result<()> { let data = fs::read("image.png")?; println!("تم قراءة {} بايت", data.len()); Ok(())}للقراءة سطرًا سطرًا، من المناسب استخدام BufReader:
fn main() -> io::Result<()> { let file = fs::File::open("data.txt")?; let reader = io::BufReader::new(file); for line in reader.lines() { let line = line?; println!("{}", line); } Ok(())}العمل مع المجلدات
يتم إنشاء مجلد جديد باستخدام fs::create_dir أو fs::create_dir_all (للمسارات المتداخلة):
fn main() -> io::Result<()> { // إنشاء مجلد واحد fs::create_dir("my_folder")?;
// إنشاء مجلدات متداخلة (مشابه لـ mkdir -p) fs::create_dir_all("a/b/c")?; println!("تم إنشاء المجلدات."); Ok(())}للتحقق من وجود ملف أو مجلد، استخدم Path::exists:
fn main() { let path = Path::new("hello.txt"); if path.exists() { println!("الملف موجود."); } else { println!("الملف غير موجود."); }}للحصول على قائمة بمحتويات مجلد، استخدم fs::read_dir:
fn main() -> io::Result<()> { let e