Go 使用bytes.Buffer与使用*bytes.NewBuffer时json.Unmarshal的差异

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": "

我在看字节包。如果我使用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)
}
使用字节运行的输出。缓冲区

[
        {"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的大小。你能在更高的层次上描述一下你想要完成什么吗?我试图将文件的内容读入缓冲区,然后解析内容。但是,如果由于文件大小过大而导致内存已满,则我的应用程序将崩溃。因此,我想先发制人地限制缓冲区的大小并设置一个上限。这样,当它达到那个上限时,我就可以出错了。按照更新答案中的描述使用。