كيفية عرض قائمة الملفات في مجلد باستخدام Rust: دليل خطوة بخطوة

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

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

ابدأ الدورة

مقدمة: لماذا قد تحتاج إلى قائمة الملفات في Rust؟

\n\n

تخيل أنك تكتب أداة نسخ احتياطي، أو محلل سجلات، أو مدير ملفات بسيط بلغة Rust. هنا تظهر مهمة أساسية ولكنها حاسمة — الحصول على قائمة بجميع الملفات في مجلد معين. قد يبدو الأمر بسيطًا، لكن في Rust، مع نظام الأنواع الصارم ونظام الملكية، حتى هذه العملية البسيطة تخفي بعض التحديات.

\n\n

سؤال "How can I list files of a directory in Rust?" هو من أكثر الأسئلة شيوعًا على Stack Overflow (آلاف المشاهدات!). وهذا ليس من قبيل الصدفة: غالبًا ما يتعثر المبتدئون مع std::fs::read_dir، ويخلطون بين التكرارات، وينسون معالجة الأخطاء. في هذا الدليل، سأعرض لك طريقتين عمليتين: بسيطة (الملفات فقط في مجلد واحد) ومتقدمة (الاجتياز التكراري لجميع المجلدات الفرعية). هيا بنا!

\n\n

1. التحضير: إنشاء مشروع جديد

\n\n

قبل كتابة الكود، دعنا ننشئ مشروعًا ثنائيًا جديدًا. افتح الطرفية ونفذ:

\n\n
cargo new list_files_rs\ncd list_files_rs
\n\n

الآن افتح src/main.rs — هنا سنكتب كل الكود. في البداية، لن نحتاج إلى تبعيات خارجية، فقط المكتبة القياسية لـ Rust — std.

\n\n

2. الطريقة الأسهل: std::fs::read_dir

\n\n

الدالة std::fs::read_dir تُرجع مكررًا (iterator) على إدخالات المجلد. كل إدخال هو DirEntry، يحتوي على الاسم، المسار، النوع، والبيانات الوصفية للملف. لنكتب مثالًا أساسيًا:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new("."); // المجلد الحالي\n\n    // قراءة محتويات المجلد\n    let entries = fs::read_dir(path)?;\n\n    for entry in entries {\n        let entry = entry?; // فك تغليف Result\n        let path = entry.path();\n\n        // التحقق من أنه ملف (وليس مجلد)\n        if path.is_file() {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

ماذا يحدث هنا؟

\n
    \n
  • fs::read_dir(path) — يفتح المجلد ويعيد ReadDir (مكرر).
  • \n
  • نمر عبر كل إدخال. كل استدعاء لـ next() يعيد Result<DirEntry> — لذلك نحتاج إلى entry?.
  • \n
  • entry.path() يعيد المسار الكامل للملف/المجلد.
  • \n
  • الطريقة path.is_file() تستبعد المجلدات الفرعية.
  • \n
\n\n

شغّل الكود باستخدام الأمر cargo run — سترى قائمة الملفات في جذر المشروع (مثل Cargo.toml، src/main.rs).

\n\n

2.1. التصفية حسب الامتداد

\n\n

غالبًا ما تحتاج إلى الحصول على ملفات معينة فقط، مثل .rs أو .txt. دعنا نضيف فلترًا:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new(".");\n\n    for entry in fs::read_dir(path)? {\n        let entry = entry?;\n        let path = entry.path();\n\n        // التحقق من أنه ملف وامتداده .rs\n        if path.is_file() && path.extension().map_or(false, |ext| ext == "rs") {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

الحيلة مع map_or ضرورية لمعالجة الحالة التي لا يحتوي فيها الملف على امتداد بأمان — path.extension() يعيد Option<&OsStr>.

\n\n

3. الاجتياز التكراري: التعمق في جميع المجلدات الفرعية

\n\n

الطريقة البسيطة read_dir لا تدخل المجلدات الفرعية. إذا كنت بحاجة إلى جمع جميع الملفات بشكل تكراري (مثلًا للبحث عن الملفات المكررة)، فسيتعين عليك كتابة دالة تكرارية خاصة بك. إليك حل أنيق:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn visit_dirs(dir: &Path, depth: usize) -> Result<(), Box<dyn std::error::Error>> {\n    for entry in fs::read_dir(dir)? {\n        let entry = entry?;\n        let path = entry.path();\n\n        if path.is_dir() {\n            // اجتياز المجلد الفرعي بشكل تكراري\n            visit_dirs(&path, depth + 1)?;\n        } else {\n            // طباعة المسافة البادئة حسب العمق\n            println!("{:indent$}{}", "", path.display(), indent = depth * 2);\n        }\n    }\n    Ok(())\n}\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new(".");\n    visit_dirs(path, 0)?;\n    Ok(())\n}
\n\n

هذا الكود سيطبع جميع الملفات والمجلدات بشكل هرمي، مع مسافة بادئة تعكس العمق. يمكنك تعديله لتصفية الملفات حسب الحاجة.

\n\n

الخلاصة

\n\n

الآن لديك طريقتان قويتان لعرض قائمة الملفات في Rust: بسيطة باستخدام read_dir، ومتقدمة باستخدام الاجتياز التكراري. تذكر دائمًا معالجة الأخطاء باستخدام Result وعدم إهمال التحقق من الأنواع. جرب الكود بنفسك وعدّله ليناسب احتياجاتك!

المدونات

توصيات الكتب