使用bytes.Buffer与使用* bytes.NewBuffer

时间:2017-03-08 01:08:31

标签: go

我在查看bytes包。如果我使用bytes.Buffer定义一个缓冲区,那么下面的代码工作,我得到一个输出。但是,如果我尝试创建具有一定容量的缓冲区,然后尝试相同的代码,则会失败,并显示错误错误:无效字符' \ x00'寻找价值的开端。不知道如何解决它。

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
)

func main() {
    var jsonBlob = []byte(`[
        {"Name": "Platypus", "Order": "Monotremata"},
            {"Name": "Quoll",    "Order": "Dasyuromorphia"}
            ]`)

    //var b bytes.Buffer
    b := *bytes.NewBuffer(make([]byte, 20))
    b.Write(jsonBlob)

    fmt.Println(b.String())

    var dat interface{}
    err := json.Unmarshal(b.Bytes(), &dat)
    if err != nil {
        fmt.Println("error:", err)
    }   
    fmt.Printf("%+v", dat)
}

使用bytes.Buffer

运行输出
[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]
[map[Name:Platypus Order:Monotremata] map[Name:Quoll Order:Dasyuromorphia]]
Program exited.

使用bytes.NewBuffer

运行输出
[
        {"Name": "Platypus", "Order": "Monotremata"},
        {"Name": "Quoll",    "Order": "Dasyuromorphia"}
    ]
error: invalid character '\x00' looking for beginning of value
<nil>

2 个答案:

答案 0 :(得分:7)

NewBuffer函数使用参数作为缓冲区的初始内容。调用make([]byte, 20)返回包含20个零字节的字节片。 b.Write(jsonBlob)之后缓冲区的内容是20个零字节,后跟JSON文本。

fmt.Printf("%q\n", b.String())添加到程序中以查看缓冲区的内容。

playground example with printf added

JSON解析器抱怨第一个零字节。

如果您的目标是设置内部缓冲区的大小,请使用以下代码:

b := bytes.NewBuffer(make([]byte, 0, 20))

调用make([]byte, 0, 20)返回容量为20的零长度切片。

playground example with zero length slice

类型为byte.Buffer的变量作为空缓冲区开始。

如果您的目标是限制读取的数据量,请使用io.LimitedReader。例如:

f, err := os.Open("filename")
if err != nil {
   // handle error
}
defer f.Close()
err := json.NewDecoder(&io.LimitedReader{N: 20, R: f}).Decode(&dat)
if err != nil {
    // handle error. Will get parse error if file is truncated. 
}

答案 1 :(得分:2)

阅读this

  

func NewBuffer

     

func NewBuffer(buf [] byte)* Buffer NewBuffer创建并初始化a   新缓冲区使用buf作为其初始内容。它的目的是   准备一个缓冲区来读取现有数据。它也可用于尺寸   用于写入的内部缓冲区。要做到这一点,buf应该有   期望的容量,但长度为零。

     

在大多数情况下,new(Buffer)(或只是声明一个Buffer变量)是   足以初始化缓冲区。

b.Write(jsonBlob)之后,因为你的缓冲区长度为零(make([]byte, 20)会创建一个20长度的切片),所以b.Bytes()是你分配的20个字节加上json的内容。然后当你执行Unmarshal时,json解析器会在开头看到20个零,当然它会抱怨。