我在查看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>
答案 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个零,当然它会抱怨。