1 回答

TA貢獻1827條經驗 獲得超8個贊
提供部分內容并非易事。有關介紹,請參閱維基百科上的字節服務。您必須處理特定的狀態代碼和標頭(請求和響應),這并不難,但您不應該自己浪費時間。
如果要提供(或從中提供)的內容是一個文件,您可以http.ServeFile()像您提到的那樣使用它來處理部分內容(范圍請求)。
如果要提供的內容不是作為文件存在,那么http.ServeContent()您的朋友是:
func ServeContent(w ResponseWriter, req *Request,
name string, modtime time.Time, content io.ReadSeeker)
是的,它還處理提供部分內容(范圍請求):
ServeContent 相對于 io.Copy 的主要好處是它可以正確處理 Range 請求、設置 MIME 類型并處理 If-Modified-Since 請求。
您需要做的就是提供內容的io.ReadSeeker“視圖”,這是必需的,以便實現可以“跳轉”到客戶端請求的部分,即需要提供服務的部分。你可能會問:怎么做?
該bytes包包含一個實現io.ReadSeeker:的類型bytes.Reader。
因此,例如,如果您將內容作為[]byte,您可能會獲得io.ReadSeeker這樣的:
var content []byte
// fill content
r := bytes.NewReader(content)
如果您沒有完整的內容[]byte怎么辦?一種選擇是提供您自己的類型的值,該值實現io.ReadSeeker.
io.ReadSeeker 是:
type ReadSeeker interface {
Reader
Seeker
}
io.Reader 包含一種方法:
Read(p []byte) (n int, err error)
io.Seeker 還包含一種方法:
Seek(offset int64, whence int) (int64, error)
您的內容可以在某處訪問,不知何故,您知道如何。Seek()被調用是為了讓您知道您的內容需要哪個部分(位置),并被Read()調用以便您可以填充傳遞的切片(以提供實際內容)。請注意,這些方法可能會被多次調用,因此您必須跟蹤您在內容(源)中的位置。如果您選擇沿著這條路走下去,請閱讀鏈接接口的文檔,以確保您符合接口的“通用合同”以避免意外錯誤。
- 1 回答
- 0 關注
- 158 瀏覽
添加回答
舉報