首頁  >  文章  >  後端開發  >  Go - 多部分 Part.Read 的正確用法

Go - 多部分 Part.Read 的正確用法

王林
王林轉載
2024-02-09 08:18:271070瀏覽

Go - 多部分 Part.Read 的正确用法

php小編新一今天為大家介紹一下Go語言中多部分Part.Read的正確用法。在處理HTTP請求時,我們經常會遇到需要讀取多部分資料的情況,例如處理檔案上傳。 Go語言的net/http套件中提供了Part.Read方法來讀取多部分數據,但是許多開發者在使用時會遇到一些問題。本文將詳細說明Part.Read的正確用法,幫助開發者更好地處理多部分數據,提高程式的穩定性和效能。讓我們一起來看看吧!

問題內容

我一直在嘗試使用multipart.part 來幫助從http 讀取非常大的檔案上傳(>20gb) - 所以我編寫了下面的程式碼,看起來效果很好:

func ReceiveMultipartRoute(w http.ResponseWriter, r *http.Request) {
    mediatype, p, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
    if err != nil {
       //...
    }
    if mediatype != "multipart/form-data" {
        //...
    }
    boundary := p["boundary"]
    reader := multipart.NewReader(r.Body, boundary)
    buffer := make([]byte, 8192)
    for {
        part, err := reader.NextPart()
        if err != nil {
            // ... 
        }
    
        f, err := os.CreateTemp("", part.FileName())
        if err != nil {
            // ...
        }
    
        for {
            numBytesRead, err := part.Read(buffer)
            // People say not to read if there's an err, but then I miss the last chunk?
            f.Write(buffer[:numBytesRead])
            if err != nil {
                if err == io.EOF {
                    break
                } else {
                    // error, abort ...
                    return
                }
            }
        }
    }
}

但是,在最裡面的 for 迴圈中,我發現我必須在檢查 eof 之前從 part.read 讀取,因為我注意到如果我事先這樣做併中斷,我會錯過最後一個區塊。但是,我注意到在許多其他文章/帖子中,人們檢查錯誤/eof,並檢查 break-ing(如果有)而不使用上次讀取的內容。我是否錯誤/安全地使用了 multipart.part.read() ?

解決方法

您以正確的方式使用multipart.part

multipart.part 是一個特定 實作 go.dev/io#reader" rel="nofollow noreferrer">io.reader。因此,您應該遵循約定並遵循io.reader 的建議。引用自文件:

呼叫者應始終在考慮錯誤 err 之前處理傳回的 n > 0 位元組。這樣做可以正確處理讀取一些位元組後發生的 i/o 錯誤以及允許的 eof 行為。

另請注意,在範例中,您將資料從 io.reader 複製到 os.fileos.file 實作 io.readerfrom 接口,因此您可以使用 file.readfrom() 方法複製資料。 p>

_, err := file.readfrom(part)
// non io.eof
if err != nil {
    return fmt.errorf("copy data: %w", err)
}

如果需要使用緩衝區,可以使用io.copybuffer()函數。但請注意,您需要隱藏 io.readerfrom 實現,否則緩衝區 將不會使用 執行複製。請參閱範例:123

_, err := io.CopyBuffer(writeFunc(file.Write), part, buffer)
// non io.EOF
if err != nil {
    return fmt.Errorf("copy data: %w", err)
}

type writeFunc func([]byte) (int, error)

func (write writeFunc) Write(data []byte) (int, error) {
        return write(data)
}

以上是Go - 多部分 Part.Read 的正確用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除