英文:
Filepath.Walk in Go not picking up folders under C: drive properly in Windows
问题
我正在使用Go中的Filepath.Walk尝试递归获取C:下的所有文件夹。然而,它只返回以$Recycle.Bin开头的子文件夹。我在这里做错了什么?
package main
import (
"fmt"
"path/filepath"
"os"
)
func main() {
array := Subfolders("C:")
for _,value := range array {
fmt.Println(value)
}
}
func Subfolders(path string) (paths []string) {
filepath.Walk(path, func(newPath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
paths = append(paths, newPath)
}
return nil
})
return paths
}
输出:
C:
C:$Recycle.Bin
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R0L9M20
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R22ZOD9
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R3LS9P4
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R4T2IGU
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R8TZIET
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R9QQZB9
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RA71HY3
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RBOC0V4.com
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RBOC0V4.com\go-fsnotify
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$REJFS3Z
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RF9A1Y6
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$ROMESWQ
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RP4CYID
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RQHMPV5
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RV0K99H
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RX54T04
我在C:下有很多其他文件夹,但它们没有被filepath.walk捕获。我想了解背后的原因。
编辑
感谢答案,我能够解决问题,如下所示:
func Subfolders(path string) (paths []string) {
filepath.Walk(path, func(newPath string, info os.FileInfo, err error) error {
if err != nil {
log.Println(err)
return filepath.SkipDir
}
if info.IsDir() {
paths = append(paths, newPath)
}
return nil
})
英文:
I am using the Filepath.Walk in Go to try to get all the folders under C: recursively. However it just returns me sub-folders starting with $Recycle.Bin. What am I doing wrong here?
package main
import (
"fmt"
"path/filepath"
"os"
)
func main() {
array := Subfolders("C:")
for _,value := range array {
fmt.Println(value)
}
}
func Subfolders(path string) (paths []string) {
filepath.Walk(path, func(newPath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
paths = append(paths, newPath)
}
return nil
})
return paths
}
Output:
C:
C:$Recycle.Bin
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R0L9M20
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R22ZOD9
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R3LS9P4
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R4T2IGU
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R8TZIET
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$R9QQZB9
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RA71HY3
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RBOC0V4.com
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RBOC0V4.com\go-fsnotify
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$REJFS3Z
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RF9A1Y6
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$ROMESWQ
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RP4CYID
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RQHMPV5
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RV0K99H
C:$Recycle.Bin\S-1-5-21-310629982-3373693989-3733510080-1000$RX54T04
I have many other folders under C: which donot get picked up by the filepath.walk. I wanted to understand what was the reason behind it.
EDIT
Thanks to the answers I was able to resolve the issue as below:-
func Subfolders(path string) (paths []string) {
filepath.Walk(path, func(newPath string, info os.FileInfo, err error) error {
if err != nil {
log.Println(err)
return filepath.SkipDir
}
if info.IsDir() {
paths = append(paths, newPath)
}
return nil
})
答案1
得分: 5
你在没有记录错误的情况下盲目返回错误。从回调函数返回一个非nil
的错误是让filepath.Walk
中止的信号。
可能是因为你没有访问某个文件,或者其他原因。
英文:
You're blindly returning errors without logging them. Returning a non-nil
error from the callback is a signal for filepath.Walk
to abort.
Presumably there is some file you don't have access to, or something.
答案2
得分: 1
你返回了一个错误,所以它停止了路径的遍历。根据规范,只要返回一个错误(除了一种特殊情况),处理就会停止。如果你想继续处理并忽略错误,只需返回nil
即可。
在我的机器上运行时,一个文件出现了“访问被拒绝”的错误,然后遍历就被中断了。之所以只看到$Recycle.Bin
是因为它恰好是目录中的第一个文件夹,在遍历到其他文件夹之前,遍历就被终止了。
英文:
You're returning an error, so it stops walking the paths. As the spec states, whenever an error is returned (besides one special case), processing stops. If you'd like to continue processing and ignore the error, just return nil
instead.
Running it on my machine gives me an Access is denied
error on one file, which then nukes the walk. The reason is only sees $Recycle.Bin
is because it happens to be the first folder in the directory, and the walk is killed before it can get to any others.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论