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

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

頻道掛起,可能沒有在正確的地方關閉

頻道掛起,可能沒有在正確的地方關閉

Go
森欄 2022-10-31 16:51:37
我正在嘗試在編寫一個小程序的同時學習 Go。程序應該盡可能高效和快速地遞歸解析 PATH 并輸出完整的文件名(包括路徑)和文件的 sha256 文件哈希。如果文件散列生成失敗,我想保留錯誤并將其添加到字符串中(在散列位置)。結果應在控制臺上返回一個字符串,如:fileXYZ||hash不幸的是,程序在某個時候掛起。我猜我的一些頻道沒有正確關閉并無限期地等待輸入。我已經嘗試了很長時間來解決這個問題,但沒有成功。有誰知道為什么輸出掛起?很多人提前感謝,也歡迎對 Go 新手的任何輸入/建議 ;-)。(我編寫了單獨的函數,因為我想在解決此問題后添加其他功能。)非常感謝!迪迪埃這是代碼:import (    "crypto/sha256"    "encoding/hex"    "flag"    "fmt"    "io"    "log"    "os"    "path/filepath"    "time")func main() {    pathParam := flag.String("path", ".", "Enter Filesystem Path to list folders")    flag.Parse()    start := time.Now()    run(*pathParam)    elapsed := time.Since(start)    log.Printf("Time elapsed: %v", elapsed)}func run(path string) {    chashes := make(chan string, 50)    cfiles := make(chan string)    go func() {        readfs(path, cfiles)        defer close(cfiles)    }()    go func() {        generateHash(cfiles, chashes)    }()    defer close(chashes)    for hash := range chashes {        fmt.Println(hash)    }}func readfs(path string, cfiles chan string) {    files, err := os.ReadDir(path)    if err != nil {        log.Fatalln(err)    }    for _, file := range files {        filename := filepath.Join(path, file.Name())        if file.IsDir() {            readfs(filename, cfiles)            continue        } else {            cfiles <- filename        }    }}func generateHash(cfiles chan string, chashes chan string) {    for filename := range cfiles {        go func(filename string) {            var checksum string            var oError bool = false            file, err := os.Open(filename)            if err != nil {                oError = true                errorMsg := "ERROR: " + err.Error()                log.Println(errorMsg)                checksum = errorMsg            }            defer file.Close()
查看完整描述

1 回答

?
波斯汪

TA貢獻1811條經驗 獲得超4個贊

以下循環掛起,因為chashes未關閉。


for hash := range chashes {

    fmt.Println(hash)

}

chashes在所有哈希器完成后通過關閉來修復。使用 sync.WaitGroup 等待哈希器完成。


func generateHash(cfiles chan string, chashes chan string) {

    var wg sync.WaitGroup

    for filename := range cfiles {

        wg.Add(1)

        go func(filename string) {

            defer wg.Done()

            var checksum string

            var oError bool = false

            file, err := os.Open(filename)

            if err != nil {

                oError = true

                errorMsg := "ERROR: " + err.Error()

                log.Println(errorMsg)

                checksum = errorMsg

            }

            defer file.Close()


            if !oError {

                hash := sha256.New()

                if _, err := io.Copy(hash, file); err != nil {

                    errorMsg := "ERROR: " + err.Error()

                    log.Println(errorMsg)

                    checksum = errorMsg

                }

                if len(checksum) == 0 {

                    checksum = hex.EncodeToString(hash.Sum(nil))

                }

            }

            chashes <- filename + "||" + checksum

        }(filename)

    } //for files


    // Wait for the hashers to complete.

    wg.Wait()


    // Close the channel to cause main() to break

    // out of for range on chashes.

    close(chashes)

}

defer close(chashes)從中刪除run()。

在 Go 操場上運行一個示例。



查看完整回答
反對 回復 2022-10-31
  • 1 回答
  • 0 關注
  • 108 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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