Go:zlib解压缩一片字节

时间:2014-07-26 15:01:09

标签: go

我正在尝试解析一个烦人的文件,其中包含许多单独的压缩段。我已经将这些段一次一个地解析为一个字节片段,我想在我去的时候解压缩它们。

这是我当前执行解压缩的代码,但不起作用。 fromto仅作为示例设置在顶部,实际上它们是由代码设置的。 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,这似乎没什么用。

如何一次性读取整个事物?

2 个答案:

答案 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相关类型。