亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何獲取目錄總大小?

如何獲取目錄總大???

Go
LEATH 2021-11-08 14:31:10
所以我試圖使用 Go 獲取目錄的總大小。到目前為止,我有這個:var dirSize int64 = 0func 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函數的范圍內?
查看完整描述

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


如果您認為這看起來更好,您可以將閉包分配給一個變量。


查看完整回答
反對 回復 2021-11-08
?
陪伴而非守候

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

}


查看完整回答
反對 回復 2021-11-08
?
慕婉清6462132

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 函數以確定的順序運行文件,因此他的解決方案足以解決這個問題,但我將把它作為一個示例,說明如何確保同時運行內部函數的安全。


查看完整回答
反對 回復 2021-11-08
  • 3 回答
  • 0 關注
  • 285 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號