如何从 http.Request 的响应中读取文件内容
How to read file content from an http.Request's response
我使用下面的代码向 HTTP 服务器发送请求。
服务器发送的响应包含那些 http headers
Content-Disposition:[attachment;filename=somefilename.csv]
Content-Type:[text/csv; charset=UTF-8]
我如何继续检索响应所附文件的内容?
baseUrl := "Some url that i call to fetch csv file"
client := http.Client{}
resp, _ := client.Get(baseUrl)
defer resp.Body.Close()
fmt.Println(resp)
// &{200 OK 200 HTTP/2.0 2 0 map[Content-Disposition:[attachment;filename=somefilename.csv] Content-Type:[text/csv; charset=UTF-8] Date:[Mon, 30 Sep 2019 09:54:08 GMT] Server:[Jetty(9.2.z-SNAPSHOT)] Vary:[Accept]] {0xc000530280} -1 [] false false map[] 0xc000156200 0xc0000c26e0}
您必须使用请求的正文。
baseUrl := "Some url that i call to fetch csv file"
client := http.Client{}
resp, _ := client.Get(baseUrl)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body) // this line.
fmt.Println(resp)
如果您必须处理多部分表单数据https://golang.org/pkg/net/http/#Request.FormFile
鉴于以下评论,
i see now after printing resp that there is a csv text but type is
http.Response i have to deal with golang.org/pkg/encoding/csv/#Reader
how to turn resp to string in order to be able reader to read it, or i
miss something else ?
OP 必须理解 http 响应 Body 实现了 io.Reader
接口。
当 http 响应从服务器返回时,正文不会作为字节片 []byte
.
直接读入内存
OP 还应注意,csv.Reader
是一种解码使用 io.Reader
的 CSV 编码内容的实现。在引擎盖下它不会将文件的全部内容保存在内存中,它会读取解码一行所需的内容并继续进行。
由于 golang 实现的这两个重要特性,将响应主体 reader 连接到 csv reader.
是简单自然的
对于这个问题,什么是 io.Reader
,OP 必须弄清楚它是任何能够通过 max len p 的块读取字节流的东西。这个接口的唯一方法的签名说明了这一点 Read([]byte) (int, error)
此接口的设计方式可最大限度地减少消耗的内存和分配。
引用链接
- https://golang.org/pkg/encoding/csv/#Reader
- https://golang.org/pkg/io/#Reader
- https://golang.org/pkg/net/http/#Response
说了那么多,最后的代码写得很简单,
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"net/http"
)
func main() {
baseUrl := "https://geolite.maxmind.com/download/geoip/misc/region_codes.csv"
client := http.Client{}
resp, err := client.Get(baseUrl)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp)
r := csv.NewReader(resp.Body)
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(record)
}
}
最简单的方法就是用ioutil.ReadAll
的方法来读全文。 body 实现了 io.Reader
接口,所以你可以用 reader 做的所有事情都可以用 body 完成。这包括将其通过管道传输到标准输出,如 mh-cbon 在他的回答中所示。
baseUrl := "Some url that i call to fetch csv file"
resp, err := http.Get(baseUrl)
if err != nil {
// do something with the error
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
// do something with the error
}
fmt.Println(string(content))
请注意,我删除了 client
。简单的 GET
调用不需要它。如果您需要更多配置,请像示例中那样使用 http.Client
。
另请注意,content
是 []byte
类型,但它可以很容易地转换为字符串,如上面在 print 语句中所做的那样。
我使用下面的代码向 HTTP 服务器发送请求。
服务器发送的响应包含那些 http headers
Content-Disposition:[attachment;filename=somefilename.csv]
Content-Type:[text/csv; charset=UTF-8]
我如何继续检索响应所附文件的内容?
baseUrl := "Some url that i call to fetch csv file"
client := http.Client{}
resp, _ := client.Get(baseUrl)
defer resp.Body.Close()
fmt.Println(resp)
// &{200 OK 200 HTTP/2.0 2 0 map[Content-Disposition:[attachment;filename=somefilename.csv] Content-Type:[text/csv; charset=UTF-8] Date:[Mon, 30 Sep 2019 09:54:08 GMT] Server:[Jetty(9.2.z-SNAPSHOT)] Vary:[Accept]] {0xc000530280} -1 [] false false map[] 0xc000156200 0xc0000c26e0}
您必须使用请求的正文。
baseUrl := "Some url that i call to fetch csv file"
client := http.Client{}
resp, _ := client.Get(baseUrl)
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body) // this line.
fmt.Println(resp)
如果您必须处理多部分表单数据https://golang.org/pkg/net/http/#Request.FormFile
鉴于以下评论,
i see now after printing resp that there is a csv text but type is http.Response i have to deal with golang.org/pkg/encoding/csv/#Reader how to turn resp to string in order to be able reader to read it, or i miss something else ?
OP 必须理解 http 响应 Body 实现了 io.Reader
接口。
当 http 响应从服务器返回时,正文不会作为字节片 []byte
.
OP 还应注意,csv.Reader
是一种解码使用 io.Reader
的 CSV 编码内容的实现。在引擎盖下它不会将文件的全部内容保存在内存中,它会读取解码一行所需的内容并继续进行。
由于 golang 实现的这两个重要特性,将响应主体 reader 连接到 csv reader.
是简单自然的对于这个问题,什么是 io.Reader
,OP 必须弄清楚它是任何能够通过 max len p 的块读取字节流的东西。这个接口的唯一方法的签名说明了这一点 Read([]byte) (int, error)
此接口的设计方式可最大限度地减少消耗的内存和分配。
引用链接
- https://golang.org/pkg/encoding/csv/#Reader
- https://golang.org/pkg/io/#Reader
- https://golang.org/pkg/net/http/#Response
说了那么多,最后的代码写得很简单,
package main
import (
"encoding/csv"
"fmt"
"io"
"log"
"net/http"
)
func main() {
baseUrl := "https://geolite.maxmind.com/download/geoip/misc/region_codes.csv"
client := http.Client{}
resp, err := client.Get(baseUrl)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println(resp)
r := csv.NewReader(resp.Body)
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Println(record)
}
}
最简单的方法就是用ioutil.ReadAll
的方法来读全文。 body 实现了 io.Reader
接口,所以你可以用 reader 做的所有事情都可以用 body 完成。这包括将其通过管道传输到标准输出,如 mh-cbon 在他的回答中所示。
baseUrl := "Some url that i call to fetch csv file"
resp, err := http.Get(baseUrl)
if err != nil {
// do something with the error
}
defer resp.Body.Close()
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
// do something with the error
}
fmt.Println(string(content))
请注意,我删除了 client
。简单的 GET
调用不需要它。如果您需要更多配置,请像示例中那样使用 http.Client
。
另请注意,content
是 []byte
类型,但它可以很容易地转换为字符串,如上面在 print 语句中所做的那样。