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

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

如何將 io.Reader 實例傳遞給 Golang 中的函數?

如何將 io.Reader 實例傳遞給 Golang 中的函數?

Go
Helenr 2022-10-17 16:03:52
我一直在處理一個問題,我必須將一個io.Reader實例作為參數放入由 api 作為端點提供的函數中。我需要做的任務是將本地文件夾上傳到公司的云存儲。func (s *server) uploadFileToPutIo(w http.ResponseWriter, r *http.Request) {    tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})    oauthClient := oauth2.NewClient(context.TODO(), tokenSource)    client := putio.NewClient(oauthClient)    var testIO io.Reader // ?     upload, err := client.Files.Upload(context.TODO(), testIO, "test", 0)    if err != nil {        log.Fatal(err)    }    fmt.Println(upload.File)    sendResponse(w, []byte("successful"), http.StatusOK)}/upload當我在 POST 方法下向這個端點發出請求時。我收到以下錯誤。2021/12/01 18:28:47 http: panic serving 127.0.0.1:61057: runtime error: invalid memory address or nil pointer dereferencegoroutine 8 [running]:net/http.(*conn).serve.func1(0xc000108d20)        /usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:1804 +0x153panic(0x1390ae0, 0x164fdd0)        /usr/local/Cellar/go/1.16.6/libexec/src/runtime/panic.go:971 +0x499io.copyBuffer(0x1462700, 0xc000026360, 0x0, 0x0, 0xc000170000, 0x8000, 0x8000, 0x0, 0x0, 0x13d5e01)        /usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:423 +0x10bio.Copy(...)        /usr/local/Cellar/go/1.16.6/libexec/src/io/io.go:382github.com/putdotio/go-putio/putio.(*FilesService).Upload(0xc000010088, 0x1468390, 0xc00001c088, 0x0, 0x0, 0x13ef46f, 0x6, 0x0, 0x170d108, 0x90, ...)        /Users/barisertas/go/pkg/mod/github.com/putdotio/go-putio/[email protected]/files.go:235 +0x187main.(*server).uploadFileToPutIo(0xc000010028, 0x1467d60, 0xc00014a2a0, 0xc000154500)        /Users/barisertas/workspace/mini-project/api/handler.go:79 +0xe5net/http.HandlerFunc.ServeHTTP(0xc000012db0, 0x1467d60, 0xc00014a2a0, 0xc000154500)        /usr/local/Cellar/go/1.16.6/libexec/src/net/http/server.go:2049 +0x44github.com/gorilla/mux.(*Router).ServeHTTP(0xc000144000, 0x1467d60, 0xc00014a2a0, 0xc000154300)        /Users/barisertas/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:210 +0xd3
查看完整描述

3 回答

?
皈依舞

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

runtime error: invalid memory address or nil pointer dereference

你肯定知道,這是因為你聲明了 anio.Reader但你沒有設置它的值,所以它仍然等于接口的默認值,即nil.

    var testIO io.Reader // ?

傳遞io.Readerto的Upload目的是提供要上傳的數據。通過傳遞io.Reader,任意數據源可以提供任意數量的字節,不受內存可用性的限制(與 不同[]byte,它需要在上傳 之前將所有數據保存在內存中)。io.Reader通常用于為這種“流式傳輸”操作提供數據。

Upload reads from given io.Reader and uploads the file contents

io.Reader應該是要上傳的數據的來源。

io.Reader可能是來自os.Open().

但它可以是任何滿足的東西io.Reader——例如,它也可以是bytes.Buffer.

它甚至可能是更深奧的東西,比如對GetObject來自 AWS 的流行 S3 服務的 API 調用的結果,它也返回一個io.ReadCloserwhich satisfies io.Reader。

io.Reader是 Go 接口如何允許獨立庫相互連接的一個很好的例子。您使用的 SDK 并不關心io.Reader它傳遞了什么;值滿足就足夠了,這是io.Reader在編譯時強制執行的要求。您可以將任何滿足io.Reader的東西傳遞給它,并且接口類型保證Upload()能夠正確處理它。

Upload需要一個io.Reader. 如果你想傳遞類似*os.Filefromos.Openio.ReadCloserfrom 之類的東西,比如 S3 GetObject,那會起作用,因為*os.Fileio.ReadCloser滿足 io.Reader。但是由于Upload需要io.Reader,您可以確信它只會調用io.Reader. 這意味著你必須在Upload被調用后自己關閉。

確保花時間了解如何io.Reader讓這個函數的輸入保持開放式,同時還要具體說明它所期望的接口。這是 Go 中最重要的概念之一。


查看完整回答
反對 回復 2022-10-17
?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

這個:


var testIO io.Reader

相當于:


testIO := io.Reader(nil)

所以這就是為什么你對零指針引用感到恐慌的原因:


2021/12/01 18:28:47 http: panic serving 127.0.0.1:61059: runtime error: invalid memory address or nil pointer dereference

goroutine 11 [running]:

io.Reader是一個允許傳遞通用值的接口,前提是它們實現了接口(即實現方法Read)。


由于您正在上傳文件,因此您的字節流應該來自操作系統文件。os.File實現了正確的Read方法 - 所以是兼容的io.Reader。


所以試試:


f, err := os.Open(uploadFilePath)

if err != nil { /* ... */ }


upload, err := client.Files.Upload(context.TODO(), f, "test", 0)


查看完整回答
反對 回復 2022-10-17
?
阿晨1998

TA貢獻2037條經驗 獲得超6個贊

當你定義一個變量時,它的初始值就是zero value那個類型的。io.Reader是一個接口,它的零值是nil。因此 nil pointer dereference error. io.Reader只需在將其傳遞給 Upload 之前對其進行初始化:


file, err := os.Open("path/to/file")

// if err != nil { ... }


upload, err := client.Files.Upload(context.TODO(), file, "test", 0)


查看完整回答
反對 回復 2022-10-17
  • 3 回答
  • 0 關注
  • 179 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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