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

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

去文件下載器

去文件下載器

Go
肥皂起泡泡 2021-06-23 17:53:38
我有以下代碼,假設通過將文件分成多個部分來下載文件。但是現在它僅適用于圖像,當我嘗試下載其他文件(如 tar 文件)時,輸出是無效文件。更新:使用os.WriteAt代替os.Write和刪除os.O_APPEND文件模式。package mainimport (    "errors"    "flag"    "fmt"    "io/ioutil"    "log"    "net/http"    "os"    "strconv")var file_url stringvar workers intvar filename stringfunc init() {    flag.StringVar(&file_url, "url", "", "URL of the file to download")    flag.StringVar(&filename, "filename", "", "Name of downloaded file")    flag.IntVar(&workers, "workers", 2, "Number of download workers")}func get_headers(url string) (map[string]string, error) {    headers := make(map[string]string)    resp, err := http.Head(url)    if err != nil {        return headers, err    }    if resp.StatusCode != 200 {        return headers, errors.New(resp.Status)    }    for key, val := range resp.Header {        headers[key] = val[0]    }    return headers, err}func download_chunk(url string, out string, start int, stop int) {    client := new(http.Client)    req, _ := http.NewRequest("GET", url, nil)    req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", start, stop))    resp, _ := client.Do(req)    defer resp.Body.Close()    body, err := ioutil.ReadAll(resp.Body)    if err != nil {        log.Fatalln(err)        return    }    file, err := os.OpenFile(out, os.O_WRONLY, 0600)    if err != nil {        if file, err = os.Create(out); err != nil {            log.Fatalln(err)            return        }    }    defer file.Close()    if _, err := file.WriteAt(body, int64(start)); err != nil {        log.Fatalln(err)        return    }    fmt.Println(fmt.Sprintf("Range %d-%d: %d", start, stop, resp.ContentLength))}func main() {    flag.Parse()    headers, err := get_headers(file_url)    if err != nil {        fmt.Println(err)    } 基本上,它只是讀取文件的長度,將其除以工作人員的數量,然后使用 HTTP 的 Range 標頭下載每個文件,下載后它會尋找寫入該塊的文件中的位置。
查看完整描述

2 回答

?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

如果你真的忽略了上面看到的許多錯誤,那么你的代碼不應該對任何文件類型可靠地工作。

但是,我想我可以在您的代碼中看到問題。我認為混合 O_APPEND 和 seek 可能是一個錯誤(這種模式應該忽略 Seek)。我建議使用(*os.File).WriteAt代替。

IIRC, O_APPEND 強制任何寫入發生在 [當前] 文件末尾。但是,download_chunk文件部分的函數實例可能會以不可預測的順序執行,從而“重新排序”文件部分。結果是一個損壞的文件。


查看完整回答
反對 回復 2021-06-28
?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

1.goroutine的順序不確定。 eg. 執行結果可能如下:

...

文件長度:20902

范圍 10451-20901:10451

范圍 0-10450:10451

...

所以塊不能只是附加。

2.當寫入chunk數據時必須有一個sys.Mutex

(我的英語很差,請忘記)


查看完整回答
反對 回復 2021-06-28
  • 2 回答
  • 0 關注
  • 233 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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