Go 使用bytes.Buffer与使用*bytes.NewBuffer时json.Unmarshal的差异
我在看字节包。如果我使用bytes.buffer定义一个缓冲区,那么下面的代码可以工作,我得到一个输出。但是,如果我尝试创建一个具有一定容量的缓冲区,然后尝试使用相同的代码,则会失败,错误为:查找值开头的无效字符“\x00”。我不知道怎么修Go 使用bytes.Buffer与使用*bytes.NewBuffer时json.Unmarshal的差异,go,Go,我在看字节包。如果我使用bytes.buffer定义一个缓冲区,那么下面的代码可以工作,我得到一个输出。但是,如果我尝试创建一个具有一定容量的缓冲区,然后尝试使用相同的代码,则会失败,错误为:查找值开头的无效字符“\x00”。我不知道怎么修 package main import ( "bytes" "encoding/json" "fmt" ) func main() { var jsonBlob = []byte(`[ {"Name": "
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)
}
使用字节运行的输出。缓冲区
[
{"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>
[
{“名称”:“鸭嘴兽”,“目”:“Monotremata”},
{“名称”:“Quoll”,“顺序”:“Dasyuromorphia”}
]
错误:查找值开头的无效字符“\x00”
函数使用参数作为缓冲区的初始内容。调用make([]字节,20)
返回一个包含20个零字节的字节片。b.Write(jsonBlob)
之后的缓冲区内容是20个零字节,后跟JSON文本
将fmt.Printf(“%q\n”,b.String())
添加到程序中以查看缓冲区的内容
JSON解析器抱怨第一个零字节
如果您的目标是设置内部缓冲区的大小,请使用以下代码:
b := bytes.NewBuffer(make([]byte, 0, 20))
调用make([]字节,0,20)
返回一个容量为20的零长度片
类型为byte.Buffer
的变量以空缓冲区开始
如果您的目标是限制读取的数据量,则使用。例如:
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.
}
阅读:
纽伯弗函数
func NewBuffer(buf[]字节)*缓冲区NewBuffer创建并初始化
使用buf作为初始内容的新缓冲区。其目的是
准备缓冲区以读取现有数据。它也可以用来调整大小
用于写入的内部缓冲区。要做到这一点,buf应该拥有
所需容量,但长度为零
在大多数情况下,new(Buffer)(或仅声明一个Buffer变量)是
足以初始化缓冲区
在
b.Write(jsonBlob)
之后,因为缓冲区的长度不为零(make([]字节,20)
创建一个20长度的片),所以b.Bytes()
是您分配的20字节加上json内容。然后,当您执行解组时,json解析器在开始时会看到20个零,当然它会抱怨。“所以b.Bytes()只有20个字节”——除非不是。@zerkms我的错误。谢谢!有没有办法限制缓冲区不增长?因为即使将容量设置为20,当大小增加时,缓冲区大小也会增加,直到溢出。要做到这一点,我需要编写自己的编写方法吗?或者有没有一种方法可以做到这一点,而不必编写我自己的自定义包装,比如eLitmus博客中的包装。(ref)无法限制bytes.Buffer的大小。你能在更高的层次上描述一下你想要完成什么吗?我试图将文件的内容读入缓冲区,然后解析内容。但是,如果由于文件大小过大而导致内存已满,则我的应用程序将崩溃。因此,我想先发制人地限制缓冲区的大小并设置一个上限。这样,当它达到那个上限时,我就可以出错了。按照更新答案中的描述使用。