使用 io.Pipe() read/write golang 下载 zip 文件
Download a zip file using io.Pipe() read/write golang
我正在尝试使用 golang 中的 io.Pipe() 函数流出 zip 文件的字节。我正在使用管道 reader 读取 zip 中每个文件的字节,然后将它们流出并使用管道编写器将字节写入响应对象。
func main() {
r, w := io.Pipe()
// go routine to make the write/read non-blocking
go func() {
defer w.Close()
bytes, err := ReadBytesforEachFileFromTheZip()
err := json.NewEncoder(w).Encode(bytes)
handleErr(err)
}()
这不是一个有效的实现,而是我想要实现的结构。我不想使用 ioutil.ReadAll,因为文件将非常大,而 Pipe() 将帮助我避免将所有数据带入内存。有人可以使用 io.Pipe() 帮助实现工作吗?
我使用 golang io.Pipe() 使其工作。Pipewriter 以块的形式将字节写入管道,pipeReader reader 从另一端写入。使用 go-routine 的原因是在从管道发生同时读取时进行非阻塞写入操作。
注意:关闭管道编写器 (w.Close()) 以在流上发送 EOF 很重要,否则它不会关闭流。
func DownloadZip() ([]byte, error) {
r, w := io.Pipe()
defer r.Close()
defer w.Close()
zip, err := os.Stat("temp.zip")
if err != nil{
return nil, err
}
go func(){
f, err := os.Open(zip.Name())
if err != nil {
return
}
buf := make([]byte, 1024)
for {
chunk, err := f.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if chunk == 0 {
break
}
if _, err := w.Write(buf[:chunk]); err != nil{
return
}
}
w.Close()
}()
body, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return body, nil
}
如果有人有其他方法,请告诉我。
我正在尝试使用 golang 中的 io.Pipe() 函数流出 zip 文件的字节。我正在使用管道 reader 读取 zip 中每个文件的字节,然后将它们流出并使用管道编写器将字节写入响应对象。
func main() {
r, w := io.Pipe()
// go routine to make the write/read non-blocking
go func() {
defer w.Close()
bytes, err := ReadBytesforEachFileFromTheZip()
err := json.NewEncoder(w).Encode(bytes)
handleErr(err)
}()
这不是一个有效的实现,而是我想要实现的结构。我不想使用 ioutil.ReadAll,因为文件将非常大,而 Pipe() 将帮助我避免将所有数据带入内存。有人可以使用 io.Pipe() 帮助实现工作吗?
我使用 golang io.Pipe() 使其工作。Pipewriter 以块的形式将字节写入管道,pipeReader reader 从另一端写入。使用 go-routine 的原因是在从管道发生同时读取时进行非阻塞写入操作。
注意:关闭管道编写器 (w.Close()) 以在流上发送 EOF 很重要,否则它不会关闭流。
func DownloadZip() ([]byte, error) {
r, w := io.Pipe()
defer r.Close()
defer w.Close()
zip, err := os.Stat("temp.zip")
if err != nil{
return nil, err
}
go func(){
f, err := os.Open(zip.Name())
if err != nil {
return
}
buf := make([]byte, 1024)
for {
chunk, err := f.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if chunk == 0 {
break
}
if _, err := w.Write(buf[:chunk]); err != nil{
return
}
}
w.Close()
}()
body, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return body, nil
}
如果有人有其他方法,请告诉我。