Liste des répertoires en Go : du simple au complexe
\n\nTravailler avec le système de fichiers est l'une des tâches de base de tout langage de programmation. En Go, elle est implémentée de manière si élégante que même une opération aussi routinière que le list directory in Go se transforme en une aventure passionnante. Si vous vous êtes déjà demandé : "Comment puis-je obtenir la liste des fichiers dans un dossier en Go ?" — vous êtes au bon endroit. Aujourd'hui, nous allons passer en revue toutes les méthodes possibles, de l'affichage simple au parcours récursif avec filtrage.
\n\nPourquoi ce sujet est-il si populaire sur Stack Overflow ? Parce que Go propose plusieurs approches, et choisir la bonne est la moitié du succès. Nous allons examiner le classique os.ReadDir, l'obsolète ioutil.ReadDir (mais on le trouve encore dans les anciens projets), et le puissant filepath.Walk pour le parcours récursif. C'est parti !
1. Liste la plus simple : os.ReadDir
\n\nDepuis Go 1.16, le package os a reçu une nouvelle méthode ReadDir, qui est devenue le standard de facto. Elle retourne une tranche d'objets os.DirEntry — des descriptions légères de fichiers et de dossiers. Voici à quoi cela ressemble :
package main\n\nimport (\n "fmt"\n "os"\n "log"\n)\n\nfunc main() {\n // Lit le contenu du répertoire courant\n entries, err := os.ReadDir(".")\n if err != nil {\n log.Fatal(err)\n }\n\n fmt.Println("Contenu du dossier courant :")\n for _, entry := range entries {\n fmt.Printf("- %s (répertoire : %v)\\n", entry.Name(), entry.IsDir())\n }\n}\n\n\nCe code affichera tous les fichiers et dossiers du répertoire courant. Notez que os.ReadDir ne lit pas les sous-dossiers — seulement le premier niveau. Si vous avez besoin d'un list directory in Go récursif, lisez la suite.
2. ioutil.ReadDir : ancien mais familier
\n\nAvant Go 1.16, tout le monde utilisait ioutil.ReadDir. Il retourne []os.FileInfo — une structure plus lourde avec des informations complètes sur le fichier (taille, droits d'accès, date de modification). Bien que la méthode soit marquée comme dépréciée, vous pouvez encore la rencontrer dans du code legacy :
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("Fichiers dans mydir (ancienne méthode) :")\n for _, file := range files {\n fmt.Printf("Nom : %s, Taille : %d octets\\n", file.Name(), file.Size())\n }\n}\n\n\nLa principale différence : ioutil.ReadDir trie le résultat par nom de fichier (comme ls), alors que os.ReadDir ne le fait pas. Si l'ordre est important, utilisez sort.Slice ou un tri manuel.
3. Parcours récursif avec filepath.Walk
\n\nLorsque vous devez parcourir tous les sous-dossiers, filepath.Walk vient à la rescousse. Cette fonction parcourt l'arborescence des répertoires, en appelant un callback pour chaque élément trouvé. Idéal pour les sauvegardes, la recherche de fichiers ou l'analyse de la structure d'un projet :
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("Trouvé : %s (taille : %d)\\n", path, info.Size())\n return nil\n })\n if err != nil {\n fmt.Println("Erreur de parcours :", err)\n }\n}\n\n\nUn point important : filepath.Walk suit les liens symboliques et peut entrer dans une boucle infinie s'il y a des références circulaires. Pour la production, utilisez filepath.WalkDir (Go 1.16+) — plus léger et plus sûr.
4. Filtrage : uniquement les fichiers .go ou uniquement les dossiers
\n\nIl est souvent nécessaire d'obtenir non pas tout, mais seulement certains types de fichiers. Implémentons un filtrage avec strings.HasSuffix et la vérification IsDir()