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

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

如何改進實現的文件下載器

如何改進實現的文件下載器

Go
忽然笑 2022-05-23 16:38:07
我正在嘗試提高我在 Go 中實現的下載器的性能。我認為我遇到了內存使用問題,因為當我嘗試下載大文件(如 1gb 或更大)時程序卡住了。我用它下載了 100mgb 和 300mgb 左右的文件,一切正常。下載器在提供標頭 Accept-Ranges 的服務器上使用。下面我將向您展示實現和主要部分,但首先讓我解釋一下。接受范圍:字節在這個實現中,我創建了一個 http.Client 來使用我請求的文件部分設置標題范圍,之后我提出了請求。為了存儲這個請求的響應,我創建了一個臨時文件,并將響應直接復制到這個文件中。這樣做的想法是避免將整個響應復制到內存中。這是實現:func DownloadPart(wg *sync.WaitGroup, tempName string, url string, part string) {    //setting up the client to make the request    client := http.Client{}    request, err := http.NewRequest("GET", url, nil)    //setting up the requests    request.Header.Set("Range", part)    response, err := client.Do(request)    checkError(err, "fatal")    defer response.Body.Close()    //creating the temporary file and copying    // the response to it    file, err := os.Create(tempName)    checkError(err, "panic")    defer file.Close()        _, err = io.Copy(file, response.Body)    checkError(err, "fatal")    defer wg.Done()}這個函數在各種 goroutine 中被調用,所以當 gorputine 結束下載部分文件時,我使用了 WaitGroup 來減少計數器。在所有這些 goroutine 結束后,我將不同的臨時文件加入到一個文件中。這是join函數的實現func joinFiles(name string) {    finalFile, err := os.OpenFile(name, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)    if err != nil {        log.Panicln(err.Error())    }    defer finalFile.Close()    files, err := ioutil.ReadDir(".")    for _, f := range files {        tempData, err := ioutil.ReadFile(f.Name())        if err != nil {            log.Panicln(err.Error())        }        if f.Name() != finalFile.Name() {            finalFile.Write(tempData)            os.Remove(f.Name())        }    }}現在我將向您展示使用這些功能的主要功能部分//start, end and rest are used to set the Range header in the requests //threads are the number of goroutines to used in the downloadvar wg sync.WaitGroupwg.Add(threads)//initializing the goroutinesfor i := 0; i < threads; i++ {    part := fmt.Sprintf("bytes=%d-%d", start, end)    start = end + 1    if i == threads-1 {        end = end + step + rest    } else {        end = end + step    }如果有辦法改進這個實現?
查看完整描述

1 回答

?
守候你守候我

TA貢獻1802條經驗 獲得超10個贊

我認為這里最大的問題是您如何將文件拼接在一起。調用ioutil.ReadAll會將整個文件的內容讀入內存,并且由于您對所有部分都執行此操作,因此您可能會在內存中結束整個文件的內容(GC 可能會在中間運行并釋放其中的一些內容。)要做的是io.Copy在文件上使用(在用打開它之后os.Open)將其復制到最終文件中。這樣您就不必將內容存儲在內存中。



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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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