Analyse du système de fichiers dans Golang

  1. Je dois écrire une fonction qui, une fois donné le chemin d’un dossier, parsing les fichiers enracinés dans ce dossier.
  2. Et puis je dois afficher la structure de répertoires dans ce dossier.

Je sais comment faire 2 (je vais utiliser jstree pour l’afficher dans le navigateur).

S’il vous plaît aidez-moi avec la partie 1, comme quoi / où commencer pour écrire une telle fonction dans go.

EDIT : Assez de gens frappent toujours cette réponse, que je pensais la mettre à jour pour l’API Go1. Ceci est un exemple de travail de filepath.Walk () . L’original est ci-dessous.

package main import ( "path/filepath" "os" "flag" "fmt" ) func visit(path ssortingng, f os.FileInfo, err error) error { fmt.Printf("Visited: %s\n", path) return nil } func main() { flag.Parse() root := flag.Arg(0) err := filepath.Walk(root, visit) fmt.Printf("filepath.Walk() returned %v\n", err) } 

Veuillez noter que filepath.Walk parcourt l’arborescence de manière récursive.

Voici un exemple:

 $ mkdir -p dir1/dir2 $ touch dir1/file1 dir1/dir2/file2 $ go run walk.go dir1 Visited: dir1 Visited: dir1/dir2 Visited: dir1/dir2/file2 Visited: dir1/file1 filepath.Walk() returned  

REPONSE ORIGINALE SUIT: L’interface pour parcourir les chemins de fichiers a été modifiée chaque semaine.2011-09-16, voir http://groups.google.com/group/golang-nuts/msg/e304dd9cf196a218 . Le code ci-dessous ne fonctionnera pas dans les prochaines versions de GO.

Il y a en fait une fonction dans la lib standard pour ceci: filepath.Walk .

 package main import ( "path/filepath" "os" "flag" ) type visitor int // THIS CODE NO LONGER WORKS, PLEASE SEE ABOVE func (v visitor) VisitDir(path ssortingng, f *os.FileInfo) bool { println(path) return true } func (v visitor) VisitFile(path ssortingng, f *os.FileInfo) { println(path) } func main() { root := flag.Arg(0) filepath.Walk(root, visitor(0), nil) } 

Voici un moyen d’obtenir des informations sur les fichiers pour les fichiers d’un répertoire.

 package main import ( "fmt" "os" "path/filepath" ) func main() { dirname := "." + ssortingng(filepath.Separator) d, err := os.Open(dirname) if err != nil { fmt.Println(err) os.Exit(1) } defer d.Close() fi, err := d.Readdir(-1) if err != nil { fmt.Println(err) os.Exit(1) } for _, fi := range fi { if fi.Mode().IsRegular() { fmt.Println(fi.Name(), fi.Size(), "bytes") } } } 

Voici un exemple pour parcourir tous les fichiers et répertoires de manière récursive. Notez que si vous voulez savoir si le chemin que vous ajoutez est un répertoire, cochez simplement “f.IsDir ()”.

 package main import ( "fmt" "os" "path/filepath" ) func main() { searchDir := "c:/path/to/dir" fileList := []ssortingng{} err := filepath.Walk(searchDir, func(path ssortingng, f os.FileInfo, err error) error { fileList = append(fileList, path) return nil }) for _, file := range fileList { fmt.Println(file) } } 

Package github.com/kr/fs fournit à Walker une API très intéressante.

Go standard package ioutil a une fonction intégrée pour ce scénario, voir l’exemple ci-dessous

 func searchFiles(dir ssortingng) { // dir is the parent directory you what to search files, err := ioutil.ReadDir(dir) if err != nil { log.Fatal(err) } for _, file := range files { fmt.Println(file.Name()) } } 

Notez que “Walk ne suit pas les liens symboliques”, donc si vous cherchez à écrire une fonction, je vous recommande ioutil.ReadDir . Mon propre test de performances a montré qu’il est plus rapide et nécessite moins de mémoire que filepath.Glob .

De plus, ioutil.ReadDir sortinge les fichiers par nom de base en utilisant une comparaison de chaînes de base ( strA > strB ). En tant que développeur de devops, je sortinge généralement les noms de répertoires en effectuant une comparaison numérique inverse (la dernière version en premier, par exemple). Si c’est également votre cas, il est préférable d’appeler directement ioutil.ReadDir ( ioutil.ReadDir appelle cela sous les couvertures) et de faire le sorting vous-même.

Voici un exemple de la partie ReadDir avec un sorting numérique:

 // ReadDirNumSort - Same as ioutil/ReadDir but uses returns a Numerically // Sorted file list. // // Taken from https://golang.org/src/io/ioutil/ioutil.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // // Modified Sort method to use Numerically sorted names instead. // It also allows reverse sorting. func ReadDirNumSort(dirname ssortingng, reverse bool) ([]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 } if reverse { sort.Sort(sort.Reverse(byName(list))) } else { sort.Sort(byName(list)) } return list, nil } // byName implements sort.Interface. type byName []os.FileInfo func (f byName) Len() int { return len(f) } func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] } func (f byName) Less(i, j int) bool { nai, err := strconv.Atoi(f[i].Name()) if err != nil { return f[i].Name() < f[j].Name() } naj, err := strconv.Atoi(f[j].Name()) if err != nil { return f[i].Name() < f[j].Name() } return nai < naj }