如何使用Golang的zlib?

huangapple go评论106阅读模式
英文:

how to use golang's zlib?

问题

var buf bytes.Buffer

var outputBuffer [100]byte
b := []byte({"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}})

w := zlib.NewWriter(&buf)
r, _ := zlib.NewReader(&buf)
w.Write(b)
w.Flush()
r.Read(outputBuffer)//cannot use outputBuffer (type [100]byte) as type []byte in function argument
fmt.Println(outputBuffer)

我该怎么做才能解决这个问题?谢谢

英文:
var buf bytes.Buffer

var outputBuffer [100]byte
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}}`)

w := zlib.NewWriter(&buf)
r, _ := zlib.NewReader(&buf)
w.Write(b)
w.Flush()
r.Read(outputBuffer)//cannot use outputBuffer (type [100]byte) as type []byte in function argument
fmt.Println(outputBuffer)

what can I do to make this right? thanks

答案1

得分: 5

好的,以下是翻译好的部分:

你试图将一个数组用作切片。它期望一个[]byte,而你给了一个[100]byte[]byte具有动态宽度,而[100]byte始终是100个字节。数组的大小是其类型的一部分;[1]int[2]int是不同的类型。这就是为什么几乎所有操作都在切片上进行的原因。

但这不是唯一的问题。当你直接在io.Reader上调用Read时,它会填充目标切片,但不会扩展它。如果你将输出切片的宽度设为10个字节(make([]byte, 10)),你将看到的输出将是{"Name":"W

但是在这一点上,你可以像标准库文档中所示的那样,直接将os.Stdout传递给io.Copy。唯一的区别是我们保留了输出格式的副本,但是...如果输出太大,你不想将其保存在内存中怎么办?这就是为什么io.Copy接受一个接口的原因:你可以获取压缩数据,并将其未压缩的版本直接写入任何输出流,包括stdout,还包括文件、Unix套接字或网络套接字。

英文:

well you tried to use an array as a slice. It expected a []byte and you gave it a [100]byte. A []byte has a dynamic width, while a [100]byte is always 100 bytes. An array's size is a part of its type; a [1]int is a different type from a [2]int. That's why almost everything operates on slices.

But that's not the only thing. When you call Read on an io.Reader directly, it fills in the target slice up to its current width, without expanding it. If you had made your output slice 10 bytes wide (make([]byte, 10)), the output you would see would be {"Name":"W.

var in bytes.Buffer
b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"],"test":{"prop1":1,"prop2":[1,2,3]}}`)
w := zlib.NewWriter(&in)
w.Write(b)
w.Close()

var out bytes.Buffer
r, _ := zlib.NewReader(&in)
io.Copy(&out, r)
os.Stdout.Write(out.Bytes())

but at this point, you might as well just pass os.Stdout into io.Copy, just like they do in the standard library docs. The only difference is we have kept a copy of the output format, but... what if the output is so large that you don't want to hold it in memory? That's why io.Copy takes an interface: you can take compressed data, and write an uncompressed version of it directly to any output stream, including stdout but also including things like files, unix sockets, or network sockets.

答案2

得分: -3

尝试以下之一:

r.Read([]byte(outputBuffer))

或者

r.Read(outputBuffer[0:100])

我相信这与Go语言中切片(slices)和固定大小数组的概念有关。你可以在这里阅读更多关于这些概念的内容(关于数组和切片的部分):

http://www.golang-book.com/6

还有其他方法,例如最初将outputBuffer设置为一个合适的切片而不是固定长度的数组,但是通过上面的指针,你应该能够解决问题。

英文:

Try one of the following:

r.Read([]byte(outputBuffer))

or

r.Read(outputBuffer[0:100])

I believe it has to do with Go's concept of slices versus fixed size arrays. You can read more about these concepts here (the sections about Arrays and Slices):

http://www.golang-book.com/6

There are other ways as well, for instance making your outputBuffer a proper slice initially instead of a fixed length array, but with the pointer above you should be able to figure it out.

huangapple
  • 本文由 发表于 2013年1月31日 17:31:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/14622422.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定