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

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

在 GO 中重組大塊 zip 下載

在 GO 中重組大塊 zip 下載

Go
慕無忌1623718 2023-05-15 14:35:05
我正在與 Accept-Ranges 和 Goroutines 并行下載一個大的 .zip 文件。該應用程序使用其 Range 標頭發送多個請求,以從 URL 下載 10MB 的 zip 文件塊。請求被分成不同的范圍作為單獨的 Goroutines,并將獲得的數據寫入臨時文件。這些文件被命名為 1、2、3....package mainimport (    "bufio"    "fmt"    "io"    "io/ioutil"    "log"    "net/http"    "os"    "strconv"    "sync")var wg sync.WaitGroupfunc main() {    url := "https://path/to/large/zip/file/zipfile.zip"    res, _ := http.Head(url)    maps := res.Header    length, _ := strconv.Atoi(maps["Content-Length"][0]) // Get the content length from the header request    chunks := (length / (1024 * 1024 * 10)) + 1    // startByte and endByte determines the positions of the chunk that should be downloaded    var startByte = 0    var endByte = (1024 * 1024 * 10) - 1    //body := make([][]byte, chunks)    body := make([]io.ReadCloser, chunks)    for i := 0; i < chunks; i++ {        wg.Add(1)        go func(min int, max int, i int) {            client := &http.Client {}            req, _ := http.NewRequest("GET", url, nil)            rangeHeader := "bytes=" + strconv.Itoa(min) +"-" + strconv.Itoa(max)            fmt.Println(rangeHeader)            req.Header.Add("Range", rangeHeader)            resp,_ := client.Do(req)            defer resp.Body.Close()            reader, _ := ioutil.ReadAll(resp.Body)            body[i] = resp.Body            ioutil.WriteFile(strconv.Itoa(i), reader, 777) // Write to the file i as a byte array            wg.Done()        }(startByte, endByte, i)        startByte = endByte + 1        endByte += 1024 * 1024 * 10    }    wg.Wait()    filepath := "zipfile.zip"    // Create the file    _, err := os.Create(filepath)    if err != nil {        return    }    file, _ := os.OpenFile(filepath, os.O_APPEND|os.O_WRONLY, os.ModeAppend)    if err != nil {        log.Fatal(err)    }下載完所有文件后,我嘗試將它們重新組合成一個 .zip 文件。但是,當文件放在一起時,我無法解壓縮最終文件,因為它似乎已損壞。我想知道我做錯了什么,或者是否有更好的方法。提前致謝。
查看完整描述

1 回答

?
紫衣仙女

TA貢獻1839條經驗 獲得超15個贊

問題在于您的范圍請求


線條


   resp,_ := client.Do(req)

   defer resp.Body.Close()

go vet由于未檢查錯誤而被報告。如果您檢查最后一個塊中的響應代碼是 416 - 這是使用的不正確范圍,請更改為


resp, err := client.Do(req)

if err != nil {

    panic(err)

}

if resp.StatusCode == 416 {

    fmt.Println("incorrect range")

}

defer resp.Body.Close()

我還將循環變量更改為for i := 0; i < chunks-1; i++ { 并更改了 go 例程之后的部分


startByte = endByte + 1

endByte += 1024 * 1024 * 10

if startByte >= length {

    break

}

for endByte >= length {

    endByte = endByte - 1

}

并以類似的方式改變 j 循環變量


這些更改似乎對我有用,但我沒有合適的測試數據來真正檢查


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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