在Golang中扫描文件系统
- 我需要编写一个函数,当给定文件夹的path扫描根目录在该文件夹的文件。
- 然后我需要在该文件夹中显示目录结构。
我知道如何做2(我打算使用jstree在浏览器中显示它)。
请帮助我第1部分,就像在哪里开始写这样的function。
编辑 :足够的人仍然打这个答案,我想我会更新它的Go1 API。 这是filepath.Walk()的一个工作示例。 原件在下面。
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) }
请注意filepath.Walkrecursion地走目录树。
这是一个示例运行:
$ 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>
原始答案如下:用于步行文件path的界面在weekly.2011-09-16中已更改,请参阅http://groups.google.com/group/golang-nuts/msg/e304dd9cf196a218 。 下面的代码不会在不久的将来发布版本的GO。
标准库中实际上只有一个函数: 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) }
这是一种获取目录中文件的文件信息的方法。
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") } } }
这是一个循环遍历所有文件和目录的例子。 请注意,如果你想知道你正在追加的path是否是一个目录,只需检查“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) } }
包github.com/kr/fs
提供了一个非常有趣的API的Walker
。
Go标准软件包ioutil
为这种情况build立了function,请参阅下面的示例
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()) } }
请注意,“走不跟随符号链接”,所以如果你正在寻找一个函数,我推荐ioutil.ReadDir 。 我自己的基准testing表明,它比filepath.Glob更快,内存更密集。
此外, ioutil.ReadDir
使用基本string比较( strA > strB
)通过基本名称sorting文件。 作为一个devops家伙,我通常通过做一个反向的数字比较来sortingdir的名字(比如最新版本)。 如果这也是你的情况,那么最好是直接调用os.ReadDir ( ioutil.ReadDir
在下面调用这个ioutil.ReadDir
)并自己进行sorting。
ReadDir
部分的一个例子是数字sorting:
// 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 }