如何递归遍历文件和目录

huangapple go评论114阅读模式
英文:

how to recursively traverse files and directories

问题

尝试运行程序时,需要显示所有的 .md 文件,我有一个名为 test 的子文件夹,其中有一个 .md 文件,但是脚本找不到它?

  1. import (
  2. "fmt"
  3. "log"
  4. "strings"
  5. "os"
  6. )
  7. func main() {
  8. dir, err := os.ReadDir(".")
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. for _, x := range dir {
  13. if strings.HasSuffix(x.Name(), ".md") {
  14. fmt.Println(x.Name())
  15. }
  16. }
  17. }
英文:

When trying to run the program is need to show all .md files, i have a test subfolder with a .md in it, but the scripts dose not find it?

  1. import (
  2. "fmt"
  3. "log"
  4. "strings"
  5. "os"
  6. )
  7. func main() {
  8. dir, err := os.ReadDir(".")
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. for _, x := range dir {
  13. if strings.HasSuffix(x.Name(), ".md") {
  14. fmt.Println(x.Name())
  15. }
  16. }
  17. }
  18. </details>
  19. # 答案1
  20. **得分**: 1
  21. 你可以使用[Walkdir][1]:
  22. ```go
  23. package main
  24. import (
  25. "io/fs"
  26. "path/filepath"
  27. )
  28. func main() {
  29. filepath.WalkDir(".", func(s string, d fs.DirEntry, e error) error {
  30. if e != nil { return e }
  31. if !d.IsDir() {
  32. println(s)
  33. }
  34. return nil
  35. })
  36. }
英文:

You can use Walkdir:

  1. package main
  2. import (
  3. &quot;io/fs&quot;
  4. &quot;path/filepath&quot;
  5. )
  6. func main() {
  7. filepath.WalkDir(&quot;.&quot;, func(s string, d fs.DirEntry, e error) error {
  8. if e != nil { return e }
  9. if ! d.IsDir() {
  10. println(s)
  11. }
  12. return nil
  13. })
  14. }

答案2

得分: 0

你需要使用filepath.WalkDir来递归检查目录,或者你可以使用在1.16版本中引入的filepath.Walkos.ReadDir只能在提供的目录内工作。

  1. filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
  2. if err != nil {
  3. fmt.Printf("处理访问路径 %q 失败时防止 panic: %v\n", path, err)
  4. return err
  5. }
  6. if strings.HasSuffix(info.Name(), ".md") {
  7. fmt.Printf("访问的文件或目录:%q\n", path)
  8. }
  9. return nil
  10. })
英文:

You need to use filepath.WalkDir to check directories recursively or you can use introduced in 1.16 filepath.Walk. os.ReadDir will work only within provided directory.

  1. filepath.Walk(&quot;.&quot;, func(path string, info fs.FileInfo, err error) error {
  2. if err != nil {
  3. fmt.Printf(&quot;prevent panic by handling failure accessing a path %q: %v\n&quot;, path, err)
  4. return err
  5. }
  6. if strings.HasSuffix(info.Name(), &quot;.md&quot;) {
  7. fmt.Printf(&quot;visited file or dir: %q\n&quot;, path)
  8. }
  9. return nil
  10. })

答案3

得分: 0

以下是使用container/ring结构的实现代码:

  1. type (
  2. DirectoryGraph struct {
  3. RootPath string
  4. root *ring.Ring
  5. Node *ring.Ring
  6. }
  7. )
  8. func NewDirectoryGraph(root string) DirectoryGraph {
  9. r := ring.New(1)
  10. graph := DirectoryGraph{
  11. RootPath: root,
  12. root: r,
  13. Node: r,
  14. }
  15. filepath.WalkDir(graph.RootPath, graph.walk)
  16. return graph
  17. }
  18. func (g DirectoryGraph) walk(s string, d fs.DirEntry, e error) error {
  19. if e != nil {
  20. return e
  21. }
  22. next := ring.New(1)
  23. node := g.serialize(s, d, e)
  24. next.Value = node
  25. g.root.Link(next).Next()
  26. return nil
  27. }
  28. // Serializes a file-node
  29. func (g DirectoryGraph) serialize(s string, d fs.DirEntry, e error) FileNode {
  30. n := FileNode{
  31. Path: s,
  32. Dir: d,
  33. Sys: SysInfo{},
  34. }
  35. ...
  36. return n
  37. }

完整代码请参考这里

英文:

To add onto the already sufficient responses here is my implementation using the container/ring structure

full code here

  1. type (
  2. DirectoryGraph struct {
  3. RootPath string
  4. root *ring.Ring
  5. Node *ring.Ring
  6. }
  7. )
  8. func NewDirectoryGraph(root string) DirectoryGraph {
  9. r := ring.New(1)
  10. graph := DirectoryGraph{
  11. RootPath: root,
  12. root: r,
  13. Node: r,
  14. }
  15. filepath.WalkDir(graph.RootPath, graph.walk)
  16. return graph
  17. }
  18. func (g DirectoryGraph) walk(s string, d fs.DirEntry, e error) error {
  19. if e != nil {
  20. return e
  21. }
  22. next := ring.New(1)
  23. node := g.serialize(s, d, e)
  24. next.Value = node
  25. g.root.Link(next).Next()
  26. return nil
  27. }
  28. // Serializes a file-node
  29. func (g DirectoryGraph) serialize(s string, d fs.DirEntry, e error) FileNode {
  30. n := FileNode{
  31. Path: s,
  32. Dir: d,
  33. Sys: SysInfo{},
  34. }
  35. ...
  36. return n
  37. }

huangapple
  • 本文由 发表于 2021年8月12日 15:10:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/68753063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定