我正在尝试解析一个烦人的文件,其中包含许多单独的压缩段。我已经将这些段一次一个地解析为一个字节片段,我想在我去的时候解压缩它们。
这是我当前执行解压缩的代码,但不起作用。 from
和to
仅作为示例设置在顶部,实际上它们是由代码设置的。 data
是包含整个文件的字节数组。我不想在磁盘上寻找它,因为它位于另一台服务器上,所以我只能先将整个文件加载到[]字节然后解析它。
from, to := 0, 1000;
b := bytes.NewReader(data[from:from+to])
z, err := zlib.NewReader(b)
CheckErr(err)
defer z.Close()
p := make([]byte,0,1024)
z.Read(p)
fmt.Println(string(p))
那么如何解压缩一段字节会如此困难?总之...
问题似乎与我如何阅读它有关。在哪里说z.Read,这似乎没什么用。
如何一次性读取整个事物?
答案 0 :(得分:3)
这是给你的大纲。注意:在Go中,检查错误!
package main
import (
"bytes"
"compress/zlib"
"fmt"
"io/ioutil"
)
func readSegment(data []byte, from, to int) ([]byte, error) {
b := bytes.NewReader(data[from : from+to])
z, err := zlib.NewReader(b)
if err != nil {
return nil, err
}
defer z.Close()
p, err := ioutil.ReadAll(z)
if err != nil {
return nil, err
}
return p, nil
}
func main() {
from, to := 0, 1000
data := make([]byte, from+to)
// ** parse input segments into data **
p, err := readSegment(data, from, to)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(p))
}
答案 1 :(得分:2)
使用ReadAll(r io.Reader) ([]byte, error)
包中的io/ioutil
。
p, err := ioutil.ReadAll(b)
fmt.Println(string(p))
Read只读取给定切片的长度(在您的情况下为1024字节)。
读取1024字节的块:
p := make([]byte,1024)
for {
numBytes, err := l.Read(p)
if err == io.EOF {
// you are done, numBytes might be less than len(p)
break
}
// do what you want with p
}
如果您从网络服务器获取数据,您甚至可以
import (
"net/http"
"io/ioutil"
)
...
resp, errGet := http.Get("http://example.com/somefile")
// do error handling
z, errZ := zlib.NewReader(resp.Body)
// do error handling
resp.Body.Close()
p, err := ioutil.ReadAll(b)
// do error handling
因为resp.Body碰巧是io.Reader,因为大多数io相关类型。