有谁知道如何打开文件、随时随地对其进行 gzip 并使用发布请求将其发送到服务器?
我有一个文件是阅读器。另外,我有http.Post()一个函数可以将阅读器作为第三个参数传递。但gzip.NewWriter()期待一个作家并返回一个作家。
我知道我可以创建一些中间缓冲区来连接这一切,但我不想分配太多内存,因为这些文件可能很大。有没有办法制作这个管道并将其传递给 HTTP post 请求?
是的,io.Pipe
reader, writer := io.Pipe()
go func() {
defer w.Close()
gw := gzip.NewWriter(w)
defer gw.Close()
gw.Write( []byte("replace with your data"))
}()
http.Post("some.url", "application/zip", reader)
Run Code Online (Sandbox Code Playgroud)
其他答案概述了如何使用 io.Pipe。这个答案显示了更多细节,特别是在错误处理方面。
func gzFileReader(fname string) (io.ReadCloser, error) {
f, err := os.Open(fname)
if err != nil {
return nil, err
}
// Use io.Pipe and a goroutine to create reader
// on data written by the appliation.
r, w := io.Pipe()
go func() {
// Always close the file.
defer f.Close()
// Copy file through gzip to pipe writer.
gzw := gzip.NewWriter(w)
_, err := io.Copy(gzw, f)
// Use CloseWithError to propgate errors back to
// the main goroutine.
if err != nil {
w.CloseWithError(err)
return
}
// Flush the gzip writer.
w.CloseWithError(gzw.Close())
}()
return r, nil
}
Run Code Online (Sandbox Code Playgroud)
使用这样的函数:
body, err := gzFileReader("example.txt")
if err != nil {
log.Fatal(err)
}
defer body.Close()
req, err := http.NewRequest("POST", "http://example.com/", body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Content-Encoding", "gzip")
resp, err := http.DefaultClient.Do(req)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
815 次 |
| 最近记录: |