go

Sistema de archivos de escaneo en Golang



(6)

  1. Necesito escribir una función que cuando se da la ruta de una carpeta escanea los archivos enraizados en esa carpeta.
  2. Y luego necesito mostrar la estructura del directorio en esa carpeta.

Sé cómo hacer 2 (voy a usar jstree para mostrarlo en el navegador).

Por favor ayúdenme con la parte 1, como qué / dónde comenzar a escribir tal función en go.


Aquí hay un ejemplo para recorrer todos los archivos y directorios recursivamente. Tenga en cuenta que si desea saber si la ruta que está agregando es un directorio simplemente marque "f.IsDir ()".

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


Aquí hay una forma de obtener información de archivos para los archivos en un directorio.

package main import ( "fmt" "os" "path/filepath" ) func main() { dirname := "." + string(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") } } }



Tenga en cuenta que "Walk no sigue enlaces simbólicos", por lo que si está buscando escribir una función que lo haga, recomiendo ioutil.ReadDir . Mi propia prueba comparativa mostró que es más rápido y filepath.Glob menos memoria que filepath.Glob .

Además, ioutil.ReadDir está ordenando archivos por nombre base usando la comparación básica de cadenas ( strA > strB ). Como un tipo devops, generalmente clasifico nombres de directorios haciendo una comparación numérica inversa (la última compilación es la primera, por ejemplo). Si ese también es su caso, entonces es mejor llamar a os.ReadDir directamente ( ioutil.ReadDir está llamando esto debajo de las coberturas) y hacer la clasificación usted mismo.

Aquí hay un ejemplo de la parte ReadDir con tipo numérico:

// 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 string, 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 }


Vaya al paquete estándar ioutil ha incorporado la función para este escenario de caso, vea el siguiente ejemplo

func searchFiles(dir string) { // 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()) } }


EDIT : toda la gente sigue respondiendo esta pregunta, y pensé que la actualizaría para la API Go1. Este es un ejemplo de trabajo de filepath.Walk() . El original está abajo.

package main import ( "path/filepath" "os" "flag" "fmt" ) func visit(path string, 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) }

Tenga en cuenta que filepath.Walk recorre el árbol de directorios recursivamente.

Este es un ejemplo de ejecución:

$ 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 <nil>

RESPUESTA ORIGINAL SIGUIENTE: La interfaz para las rutas de acceso de archivos ha cambiado a partir de las semanas.2011-09-16, consulte http://groups.google.com/group/golang-nuts/msg/e304dd9cf196a218 . El código siguiente no funcionará para versiones de lanzamiento de GO en el futuro cercano.

De hecho, hay una función en la lib estándar solo para esto: 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 string, f *os.FileInfo) bool { println(path) return true } func (v visitor) VisitFile(path string, f *os.FileInfo) { println(path) } func main() { root := flag.Arg(0) filepath.Walk(root, visitor(0), nil) }