Dans cet article, j'explique comment obtenir une liste de fichiers dans un dossier du système de fichiers, une tâche également appeléearbre traversant, avec Go.
Il existe deux fonctions stdlib pratiques que vous pouvez utiliser en fonction de votre objectif.
Je liste 3 façons: en utilisantfilepath.Walk
,ioutil.ReadDir
ouos.File.Readdir
.
Utilisantfilepath.Walk
Lepath/filepath
Le paquet stdlib fournit la fonction pratique Walk. Cependant, il scanne automatiquement les sous-répertoires, alors assurez-vous que c'est ce que vous voulez réellement.
L'utilisation est très simple:
package main
import (
“fmt”
“os”
“path/filepath”
)
func main() {
var files []string
<span style="color:#a6e22e">root</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">"/some/folder/to/scan"</span>
<span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">filepath</span>.<span style="color:#a6e22e">Walk</span>(<span style="color:#a6e22e">root</span>, <span style="color:#66d9ef">func</span>(<span style="color:#a6e22e">path</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">info</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">FileInfo</span>, <span style="color:#a6e22e">err</span> <span style="color:#66d9ef">error</span>) <span style="color:#66d9ef">error</span> {
<span style="color:#a6e22e">files</span> = append(<span style="color:#a6e22e">files</span>, <span style="color:#a6e22e">path</span>)
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
})
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
panic(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>)
}
}
filepath.Walk
accepte une chaîne pointant vers le dossier racine, et unWalkFunc
, un type de fonction avec signature
type WalkFunc func(path string, info os.FileInfo, err error) error
Cette fonction est appelée à chaque itération de l'analyse des dossiers.
Leinfo
variable de typeos.FileInfo
est important car nous pouvons obtenir de nombreuses informations sur le fichier courant: le nom, la taille, le mode, l'heure de modification, s'il s'agit d'un dossier ou d'un fichier, et la source de données sous-jacente.
Par exemple, nous pourrions éviter de traiter des dossiers en ajoutant
if info.IsDir() {
return nil
}
Vous pouvez exclure (ou inclure) des fichiers dans la tranche en fonction de leur extension, en utilisantfilepath.Ext
et en passant le chemin du fichier:
if filepath.Ext(path) == ".dat" {
return nil
}
Nous pourrions stocker le nom du fichier au lieu du chemin du fichier en utilisant
files = append(files, info.Name())
Et nous pourrions également définir leWalkFunc
dans un autrefermeture. Nous avons juste besoin de passer un pointeur versfiles
dansvisit
:
package main
import (
“fmt”
“log”
“os”
“path/filepath”
)
func visit(files []string) filepath.WalkFunc {
return func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Fatal(err)
}
files = append(*files, path)
return nil
}
}
func main() {
var files []string
<span style="color:#a6e22e">root</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">"/some/folder/to/scan"</span>
<span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">filepath</span>.<span style="color:#a6e22e">Walk</span>(<span style="color:#a6e22e">root</span>, <span style="color:#a6e22e">visit</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">files</span>))
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
panic(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>)
}
}
Utilisantioutil.ReadDir
filepath.Walk
est pratique mais analyse également les sous-dossiers, par défaut, ce qui n'est peut-être pas ce que vous souhaitez.
Le Go stdlib fournit égalementioutil.ReadDir
func ReadDir(dirname string) ([]os.FileInfo, error)
ReadDir lit le répertoire nommé par dirname et renvoie une liste d'entrées de répertoire triées par nom de fichier.
et voici un exemple tiré de la documentation.ioutil.ReadDir
prend un chemin de dossier sous forme de chaîne et renvoie une tranche deos.FileInfo
, que nous avons décrit ci-dessus.
package main
import (
“fmt”
“io/ioutil”
“log”
)
func main() {
files, err := ioutil.ReadDir(".")
if err != nil {
log.Fatal(err)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>.<span style="color:#a6e22e">Name</span>())
}
}
Utilisantos.File.Readdir
Intérieurement,ioutil.ReadDir
est implémenté comme
// ReadDir reads the directory named by dirname and returns
// a list of directory entries sorted by filename.
func ReadDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
list, err := f.Readdir(-1)
f.Close()
if err != nil {
return nil, err
}
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
return list, nil
}
comme vous pouvez le voir scannedirname
et trie les fichiers par nom. Si vous n'avez pas besoin de trier, vous pouvez également utiliser
package main
import (
“fmt”
“log”
“os”
)
func main() {
dirname := “.”
<span style="color:#a6e22e">f</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Open</span>(<span style="color:#a6e22e">dirname</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}
<span style="color:#a6e22e">files</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Readdir</span>(<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>)
<span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Close</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>.<span style="color:#a6e22e">Name</span>())
}
}
Plus de tutoriels go:
- Utilisation du proxy inverse NGINX pour servir les services Go
- Faire une copie d'une structure dans Go
- Les bases d'un serveur Web Go
- Trier un type de carte dans Go
- Allez les pointeurs en un mot
- Go Tags expliqué
- Aller au formatage de la date et de l'heure
- Traitement JSON avec Go
- Fonctions Go Variadic
- Fiche de triche Go Strings
- L'interface Go Empty expliquée
- Débogage Go avec VS Code et Delve
- Named Go renvoie des paramètres
- Générer des nombres et des chaînes aléatoires dans Go
- Structure du système de fichiers d'un projet Go
- Algorithme de recherche binaire implémenté dans Go
- Utilisation des indicateurs de ligne de commande dans Go
- GOPATH a expliqué
- Créez une application de ligne de commande avec Go: lolcat
- Création d'une commande CLI avec Go: cowsay
- Utilisation de Shell Pipes avec Go
- Tutoriel Go CLI: Clone de fortune
- Lister les fichiers dans un dossier avec Go
- Utilisez Go pour obtenir une liste des référentiels à partir de GitHub
- Allez, ajoutez une tranche de chaînes à un fichier
- Allez, convertissez une chaîne en une tranche d'octets
- Visualisez vos contributions Git locales avec Go
- Premiers pas avec Go CPU et profilage de la mémoire
- Résolution de l'erreur "ne prend pas en charge l'indexation" dans un programme Go
- Mesure du temps d'exécution dans un programme Go
- Création d'un robot d'exploration Web avec Go pour détecter les titres en double
- Go Best Practices: pointeur ou récepteurs de valeur?
- Go Best Practices: Devez-vous utiliser une méthode ou une fonction?
- Go Structures de données: définir
- Aide-mémoire Go Maps
- Générer des implémentations pour les types génériques dans Go
- Go Data Structures: Dictionnaire
- Structures de données Go: table de hachage
- Implémenter des écouteurs d'événements dans Passer par les canaux
- Go Structures de données: pile
- Go Structures de données: file d'attente
- Go Structures de données: arbre de recherche binaire
- Go Structures de données: graphique
- Structures de données Go: liste liée
- Le guide complet des structures de données Go
- Comparaison des valeurs Go
- Est-ce que Go est orienté objet?
- Travailler avec une base de données SQL dans Go
- Utilisation des variables d'environnement dans Go
- Tutoriel Go: API REST soutenue par PostgreSQL
- Activation de CORS sur un serveur Web Go
- Déployer une application Go dans un conteneur Docker
- Pourquoi Go est un langage puissant à apprendre en tant que développeur PHP
- Allez, supprimez le caractère de nouvelle ligne io.Reader.ReadString
- Allez, comment observer les changements et reconstruire votre programme
- Allez, comptez les mois depuis une date
- Accéder aux paramètres HTTP POST dans Go