如何获取目录总大小?

所以我试图使用 Go 获取目录的总大小。到目前为止,我有这个:


var dirSize int64 = 0


func readSize(path string, file os.FileInfo, err error) error {

    if !file.IsDir() {

        dirSize += file.Size()

    }

    return nil


func DirSizeMB(path string) float64 {

    dirSize = 0

    filepath.Walk(path, readSize)

    sizeMB := float64(dirSize) / 1024.0 / 1024.0

    sizeMB = Round(sizeMB, .5, 2)

    return sizeMB

}

问题是dirSize全局变量是否会导致问题,如果会,我如何将其移动到DirSizeMB函数的范围内?


LEATH
浏览 217回答 3
3回答

浮云间

使用这样的全局充其量是不好的做法。如果DirSizeMB同时被调用,这也是一场比赛。简单的解决方案是使用闭包,例如:func DirSize(path string) (int64, error) {    var size int64    err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {        if err != nil {            return err        }        if !info.IsDir() {            size += info.Size()        }        return err    })    return size, err}Playground如果您认为这看起来更好,您可以将闭包分配给一个变量。

陪伴而非守候

如果你想使用一个变量,你可以这样做:func DirSizeMB(path string) float64 {    var dirSize int64 = 0    readSize := func(path string, file os.FileInfo, err error) error {        if !file.IsDir() {            dirSize += file.Size()        }        return nil    }    filepath.Walk(path, readSize)        sizeMB := float64(dirSize) / 1024.0 / 1024.0    return sizeMB}

慕婉清6462132

您可以做的一件事是在 内部定义一个通道DirSizeMB,并readSize在该函数内部定义,以便将通道作为闭包。然后将所有尺寸发送出通道并在您收到它们时将它们相加。func DirSizeMB(path string) float64 {&nbsp; &nbsp; sizes := make(chan int64)&nbsp; &nbsp; readSize := func(path string, file os.FileInfo, err error) error {&nbsp; &nbsp; &nbsp; &nbsp; if err != nil || file == nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return nil // Ignore errors&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if !file.IsDir() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sizes <- file.Size()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return nil&nbsp; &nbsp; }&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; filepath.Walk(path, readSize)&nbsp; &nbsp; &nbsp; &nbsp; close(sizes)&nbsp; &nbsp; }()&nbsp; &nbsp; size := int64(0)&nbsp; &nbsp; for s := range sizes {&nbsp; &nbsp; &nbsp; &nbsp; size += s&nbsp; &nbsp; }&nbsp; &nbsp; sizeMB := float64(size) / 1024.0 / 1024.0&nbsp; &nbsp; sizeMB = Round(sizeMB, 0.5, 2)&nbsp; &nbsp; return sizeMB}http://play.golang.org/p/zzKZu0cm9n为什么要使用频道?除非您已阅读底层代码,否则您实际上并不知道如何filepath.Walk调用 readSize 函数。虽然它可能会在给定路径上的所有文件上顺序调用它,但该实现理论上可以在单独的 goroutines 上同时调用其中的几个调用(如果有的话,文档可能会提到这一点)。无论如何,在为并发设计的语言中,确保您的代码安全是一种很好的做法。@DaveC 给出的答案显示了如何通过对局部变量使用闭包来解决具有全局变量的问题,因此对 DirSize 的多个同时调用将是安全的。Walk 的 Docs 明确指出 walk 函数以确定的顺序运行文件,因此他的解决方案足以解决这个问题,但我将把它作为一个示例,说明如何确保同时运行内部函数的安全。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go