如何递归遍历文件和目录

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

how to recursively traverse files and directories

问题

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


import (
	"fmt"
	"log"
	"strings"
	"os"
)

func main() {

	dir, err := os.ReadDir(".")

	if err != nil {
		log.Fatal(err)
	}

	for _, x := range dir {
		if strings.HasSuffix(x.Name(), ".md") {
			fmt.Println(x.Name())
		}
	}
}
英文:

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?


import (
	"fmt"
	"log"
	"strings"
	"os"
)

func main() {

	dir, err := os.ReadDir(".")

	if err != nil {
		log.Fatal(err)
	}

	for _, x := range dir {
		if strings.HasSuffix(x.Name(), ".md") {
			fmt.Println(x.Name())
		}
	}
}


</details>


# 答案1
**得分**: 1

你可以使用[Walkdir][1]:

```go
package main

import (
   "io/fs"
   "path/filepath"
)

func main() {
   filepath.WalkDir(".", func(s string, d fs.DirEntry, e error) error {
      if e != nil { return e }
      if !d.IsDir() {
         println(s)
      }
      return nil
   })
}
英文:

You can use Walkdir:

package main

import (
   &quot;io/fs&quot;
   &quot;path/filepath&quot;
)


func main() {
   filepath.WalkDir(&quot;.&quot;, func(s string, d fs.DirEntry, e error) error {
	if e != nil { return e }
	if ! d.IsDir() {
	   println(s)
	}
	return nil
 })
}

答案2

得分: 0

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

filepath.Walk(".", func(path string, info fs.FileInfo, err error) error {
    if err != nil {
        fmt.Printf("处理访问路径 %q 失败时防止 panic: %v\n", path, err)
        return err
    }

    if strings.HasSuffix(info.Name(), ".md") {
        fmt.Printf("访问的文件或目录:%q\n", path)
    }

    return nil
})
英文:

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.

filepath.Walk(&quot;.&quot;, func(path string, info fs.FileInfo, err error) error {
	if err != nil {
		fmt.Printf(&quot;prevent panic by handling failure accessing a path %q: %v\n&quot;, path, err)
		return err
	}

	if strings.HasSuffix(info.Name(), &quot;.md&quot;) {
		fmt.Printf(&quot;visited file or dir: %q\n&quot;, path)
	}

	return nil
})

答案3

得分: 0

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

type (
	DirectoryGraph struct {
		RootPath string
		root     *ring.Ring
		Node     *ring.Ring
	}
)

func NewDirectoryGraph(root string) DirectoryGraph {
	r := ring.New(1)
	graph := DirectoryGraph{
		RootPath: root,
		root:     r,
		Node:     r,
	}
	filepath.WalkDir(graph.RootPath, graph.walk)
	return graph
}

func (g DirectoryGraph) walk(s string, d fs.DirEntry, e error) error {
	if e != nil {
		return e
	}
	next := ring.New(1)
	node := g.serialize(s, d, e)
	next.Value = node
	g.root.Link(next).Next()
	return nil
}

// Serializes a file-node
func (g DirectoryGraph) serialize(s string, d fs.DirEntry, e error) FileNode {
	n := FileNode{
		Path: s,
		Dir:  d,
		Sys:  SysInfo{},
	}

    ...

	return n
}

完整代码请参考这里

英文:

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

full code here


type (
	DirectoryGraph struct {
		RootPath string
		root     *ring.Ring
		Node     *ring.Ring
	}
)

func NewDirectoryGraph(root string) DirectoryGraph {
	r := ring.New(1)
	graph := DirectoryGraph{
		RootPath: root,
		root:     r,
		Node:     r,
	}
	filepath.WalkDir(graph.RootPath, graph.walk)
	return graph
}

func (g DirectoryGraph) walk(s string, d fs.DirEntry, e error) error {
	if e != nil {
		return e
	}
	next := ring.New(1)
	node := g.serialize(s, d, e)
	next.Value = node
	g.root.Link(next).Next()
	return nil
}

// Serializes a file-node
func (g DirectoryGraph) serialize(s string, d fs.DirEntry, e error) FileNode {
	n := FileNode{
		Path: s,
		Dir:  d,
		Sys:  SysInfo{},
	}

    ...

	return n
}


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:

确定