3 回答

TA貢獻1829條經驗 獲得超4個贊
使用這樣的全局充其量是不好的做法。如果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
如果您認為這看起來更好,您可以將閉包分配給一個變量。

TA貢獻1757條經驗 獲得超8個贊
如果你想使用一個變量,你可以這樣做:
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
}

TA貢獻1804條經驗 獲得超2個贊
您可以做的一件事是在 內部定義一個通道DirSizeMB,并readSize在該函數內部定義,以便將通道作為閉包。然后將所有尺寸發送出通道并在您收到它們時將它們相加。
func DirSizeMB(path string) float64 {
sizes := make(chan int64)
readSize := func(path string, file os.FileInfo, err error) error {
if err != nil || file == nil {
return nil // Ignore errors
}
if !file.IsDir() {
sizes <- file.Size()
}
return nil
}
go func() {
filepath.Walk(path, readSize)
close(sizes)
}()
size := int64(0)
for s := range sizes {
size += s
}
sizeMB := float64(size) / 1024.0 / 1024.0
sizeMB = Round(sizeMB, 0.5, 2)
return sizeMB
}
http://play.golang.org/p/zzKZu0cm9n
為什么要使用頻道?
除非您已閱讀底層代碼,否則您實際上并不知道如何filepath.Walk調用 readSize 函數。雖然它可能會在給定路徑上的所有文件上順序調用它,但該實現理論上可以在單獨的 goroutines 上同時調用其中的幾個調用(如果有的話,文檔可能會提到這一點)。無論如何,在為并發設計的語言中,確保您的代碼安全是一種很好的做法。
@DaveC 給出的答案顯示了如何通過對局部變量使用閉包來解決具有全局變量的問題,因此對 DirSize 的多個同時調用將是安全的。Walk 的 Docs 明確指出 walk 函數以確定的順序運行文件,因此他的解決方案足以解決這個問題,但我將把它作為一個示例,說明如何確保同時運行內部函數的安全。
- 3 回答
- 0 關注
- 285 瀏覽
添加回答
舉報