قائمة الدليل في Go: دليل كامل مع أمثلة الكود

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

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

ابدأ الدورة

قائمة الدليل في Go: من البسيط إلى المعقد

\n\n

العمل مع نظام الملفات هو أحد المهام الأساسية لأي لغة برمجة. في Go، تم تنفيذه بأناقة لدرجة أن حتى العملية الروتينية مثل list directory in Go تتحول إلى مغامرة ممتعة. إذا كنت قد تساءلت يومًا: "كيف يمكنني الحصول على قائمة الملفات في مجلد باستخدام Go؟" فقد وصلت إلى المكان الصحيح. اليوم سنستعرض جميع الطرق الممكنة، من الإخراج البسيط إلى الاجتياز التكراري مع التصفية.

\n\n

لماذا هذا الموضوع شائع جدًا على Stack Overflow؟ لأن Go يقدم عدة طرق، واختيار الطريقة الصحيحة هو نصف النجاح. سنناقش الطريقة الكلاسيكية os.ReadDir، والطريقة القديمة ioutil.ReadDir (ولكن لا يزال من الممكن العثور عليها في المشاريع القديمة)، والطريقة القوية filepath.Walk للاجتياز التكراري. هيا بنا!

\n\n

1. أبسط قائمة: os.ReadDir

\n\n

بدءًا من Go 1.16، حصلت حزمة os على طريقة جديدة ReadDir، والتي أصبحت المعيار الفعلي. تقوم بإرجاع شريحة من كائنات os.DirEntry - أوصاف خفيفة الوزن للملفات والمجلدات. إليك كيف يبدو ذلك:

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n    "log"\n)\n\nfunc main() {\n    // قراءة محتويات الدليل الحالي\n    entries, err := os.ReadDir(".")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println("محتويات المجلد الحالي:")\n    for _, entry := range entries {\n        fmt.Printf("- %s (دليل: %v)\\n", entry.Name(), entry.IsDir())\n    }\n}\n
\n\n

سيقوم هذا الكود بعرض جميع الملفات والمجلدات في الدليل الحالي. لاحظ: os.ReadDir لا يقرأ المجلدات الفرعية - فقط المستوى الأول. إذا كنت بحاجة إلى list directory in Go بشكل تكراري، تابع القراءة.

\n\n

2. ioutil.ReadDir: قديم ولكنه مألوف

\n\n

قبل إصدار Go 1.16، كان الجميع يستخدمون ioutil.ReadDir. يقوم بإرجاع []os.FileInfo - هيكل أثقل يحتوي على معلومات كاملة عن الملف (الحجم، أذونات الوصول، وقت التعديل). على الرغم من أن الطريقة تم وضع علامة عليها كمهملة، إلا أنه لا يزال بإمكانك العثور عليها في الكود القديم:

\n\n
package main\n\nimport (\n    "fmt"\n    "io/ioutil"\n    "log"\n)\n\nfunc main() {\n    files, err := ioutil.ReadDir("./mydir")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println("الملفات في mydir (الطريقة القديمة):")\n    for _, file := range files {\n        fmt.Printf("الاسم: %s, الحجم: %d بايت\\n", file.Name(), file.Size())\n    }\n}\n
\n\n

الفرق الرئيسي: ioutil.ReadDir يقوم بفرز النتيجة حسب اسم الملف (مثل ls)، بينما os.ReadDir لا يفعل ذلك. إذا كان الترتيب مهمًا، استخدم sort.Slice أو الفرز يدويًا.

\n\n

3. الاجتياز التكراري باستخدام filepath.Walk

\n\n

عندما تحتاج إلى المرور عبر جميع المجلدات الفرعية، تأتي filepath.Walk للإنقاذ. هذه الدالة تجتاز شجرة الدليل، وتستدعي دالة رد لكل عنصر يتم العثور عليه. مثالية للنسخ الاحتياطي، أو البحث عن الملفات، أو تحليل هيكل المشروع:

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n    "path/filepath"\n)\n\nfunc main() {\n    root := "./myproject"\n    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {\n        if err != nil {\n            return err\n        }\n        fmt.Printf("تم العثور على: %s (الحجم: %d)\\n", path, info.Size())\n        return nil\n    })\n    if err != nil {\n        fmt.Println("خطأ في الاجتياز:", err)\n    }\n}\n
\n\n

نقطة مهمة: filepath.Walk يتبع الروابط الرمزية وقد يدخل في حلقة لا نهائية إذا كانت هناك روابط دائرية. للإنتاج، استخدم filepath.WalkDir (Go 1.16+) - فهو أخف وأكثر أمانًا.

\n\n

4. التصفية: ملفات .go فقط أو المجلدات فقط

\n\n

غالبًا ما تحتاج إلى الحصول على أنواع معينة فقط من الملفات، وليس كل شيء. دعنا ننفذ التصفية باستخدام strings.HasSuffix والتحقق من IsDir()

المدونات

توصيات الكتب