在Windows中,Go语言中的Filepath.Walk无法正确识别C盘下的文件夹。

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

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.

huangapple
  • 本文由 发表于 2015年10月16日 21:40:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/33171991.html
匿名

发表评论

匿名网友

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

确定