Go - 在当前目录中遍历 directores/files
Go - Iterate through directores/files in current directory
我有以下结构:
project/
docs/
index.html
root.html
我正在尝试遍历此项目结构,以便我可以读取每个文件的内容来处理它们。所以我想说 "search through the directory project",然后它会搜索所有文件,并且只搜索 第一级目录 和它们的文件,所以如果有另一个目录有一个文件在 docs/
内,它会忽略它。
目前,我已尝试使用 "path/filepath" 库来实现此目的:
func traverse(path string, file os.FileInfo, err error) error {
if file, err := os.Open(file.Name()); err == nil {
defer file.Close()
if fileStat, err := file.Stat(); err == nil {
switch mode := fileStat.Mode(); {
case mode.IsDir():
fmt.Println("it be a directory! lets traverse", file.Name())
filepath.Walk(file.Name(), traverse)
case mode.IsRegular():
fmt.Println("the thingy ", file.Name(), " is a file")
}
} else {
return errors.New("failed to check status")
}
}
return errors.New("failed 2 open file/dir?")
}
然后我从这里调用它:
if err := filepath.Walk("project/", traverse); err != nil {
setupErr("%s", err)
}
请注意,我 运行 这个可执行文件相对于我的测试目录,所以它可以找到目录。我的问题实际上是当我 运行 它时,我得到以下信息:
it be a directory! lets traverse project
it be a directory! lets traverse project
# ^ printed about 20 more times ^
failed 2 open file/dir?
我觉得我的递归有点不对劲,也许它没有改变到目录中?任何想法,如果您需要更多信息,请询问,我会更新。
Walk walks the file tree rooted at root, calling walkFn for each file
or directory in the tree, including root. All errors that arise
visiting files and directories are filtered by walkFn. The files are
walked in lexical order, which makes the output deterministic but
means that for very large directories Walk can be inefficient. Walk
does not follow symbolic links.
首先,您想要执行的操作似乎与您拥有的代码相矛盾。您写道:
So I want to say "search through the directory project", then it will search through all the files, and only the first level of directories and their files, so if there was another directory with a file inside of docs/, it would ignore it.
是否意味着您只想迭代两级目录(当前目录和下一级目录)而忽略其余目录?
如果是这样,则不需要递归,只需一个简单的循环即可对当前目录及其每个子目录中的文件执行搜索功能。
您拥有的代码遍历文件系统目录子树。
基本上,您使用的 filepath.Walk
应该会为您完成。因此,您要么实现递归遍历,要么使用 Walk,但不能同时使用。
其次,递归在您的代码中实现不正确。它缺少对目录的迭代。
所以打印当前目录及其子目录(但不是更远)中的文件名的代码是:
package main
import (
"fmt"
"io/ioutil"
)
func main() {
items, _ := ioutil.ReadDir(".")
for _, item := range items {
if item.IsDir() {
subitems, _ := ioutil.ReadDir(item.Name())
for _, subitem := range subitems {
if !subitem.IsDir() {
// handle file there
fmt.Println(item.Name() + "/" + subitem.Name())
}
}
} else {
// handle file there
fmt.Println(item.Name())
}
}
}
我有以下结构:
project/
docs/
index.html
root.html
我正在尝试遍历此项目结构,以便我可以读取每个文件的内容来处理它们。所以我想说 "search through the directory project",然后它会搜索所有文件,并且只搜索 第一级目录 和它们的文件,所以如果有另一个目录有一个文件在 docs/
内,它会忽略它。
目前,我已尝试使用 "path/filepath" 库来实现此目的:
func traverse(path string, file os.FileInfo, err error) error {
if file, err := os.Open(file.Name()); err == nil {
defer file.Close()
if fileStat, err := file.Stat(); err == nil {
switch mode := fileStat.Mode(); {
case mode.IsDir():
fmt.Println("it be a directory! lets traverse", file.Name())
filepath.Walk(file.Name(), traverse)
case mode.IsRegular():
fmt.Println("the thingy ", file.Name(), " is a file")
}
} else {
return errors.New("failed to check status")
}
}
return errors.New("failed 2 open file/dir?")
}
然后我从这里调用它:
if err := filepath.Walk("project/", traverse); err != nil {
setupErr("%s", err)
}
请注意,我 运行 这个可执行文件相对于我的测试目录,所以它可以找到目录。我的问题实际上是当我 运行 它时,我得到以下信息:
it be a directory! lets traverse project
it be a directory! lets traverse project
# ^ printed about 20 more times ^
failed 2 open file/dir?
我觉得我的递归有点不对劲,也许它没有改变到目录中?任何想法,如果您需要更多信息,请询问,我会更新。
Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not follow symbolic links.
首先,您想要执行的操作似乎与您拥有的代码相矛盾。您写道:
So I want to say "search through the directory project", then it will search through all the files, and only the first level of directories and their files, so if there was another directory with a file inside of docs/, it would ignore it.
是否意味着您只想迭代两级目录(当前目录和下一级目录)而忽略其余目录?
如果是这样,则不需要递归,只需一个简单的循环即可对当前目录及其每个子目录中的文件执行搜索功能。
您拥有的代码遍历文件系统目录子树。
基本上,您使用的 filepath.Walk
应该会为您完成。因此,您要么实现递归遍历,要么使用 Walk,但不能同时使用。
其次,递归在您的代码中实现不正确。它缺少对目录的迭代。
所以打印当前目录及其子目录(但不是更远)中的文件名的代码是:
package main
import (
"fmt"
"io/ioutil"
)
func main() {
items, _ := ioutil.ReadDir(".")
for _, item := range items {
if item.IsDir() {
subitems, _ := ioutil.ReadDir(item.Name())
for _, subitem := range subitems {
if !subitem.IsDir() {
// handle file there
fmt.Println(item.Name() + "/" + subitem.Name())
}
}
} else {
// handle file there
fmt.Println(item.Name())
}
}
}