更改以JSON对象的字节表示形式归档

时间:2018-08-31 10:24:23

标签: go

我将A对象写入文件f

a := A{42}
bytes, _ := json.MarshalIndent(a, "", "\t")
f.Write(bytes)

A如下所示:

type A struct {
    A int `json:"a"`
} 

然后我更改此对象的字段并将其写入文件:

a.A = 666
f.Write(bytes)

结果,我只能看到

{
    "a": 42
}{
    "a": 42
}

虽然我期望:

{
    "a": 42
}{
    "a": 666
}

我知道我可以再次使用json.MarshalIndent来克服它。但是我需要对文件进行大量(〜10 ^ 6)的编写,因此一次又一次地使用json.MarshalIndent似乎是一项繁重的工作。

如何直接更改bytes变量?

代码位于https://play.golang.org/p/8CMpwehMidR

2 个答案:

答案 0 :(得分:3)

您别无选择,只能反复集结。使用*json.Encoder来提高人体工程学和效率:

package main

import (
    "encoding/json"
    "log"
    "os"
)

type A struct {
    A int `json:"a"`
}

func main() {
    f, err := os.Create("foo.json")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    enc := json.NewEncoder(f)
    enc.SetIndent("", "\t")

    a := A{42} // Using a pointer may improve performance if A is large.
    enc.Encode(a)

    a.A = 666
    enc.Encode(a)
}

buffered writer包裹文件也可以提高性能,这取决于您可以多快地计算连续的As值和磁盘有多快。

答案 1 :(得分:0)

您可以使用标准库替换给定字节片中的字节。

https://golang.org/pkg/bytes/#Replace

package main

import (
    "bufio"
    "bytes"
    "encoding/json"
    "os"
)

type A struct {
    A int `json:"a"`
}

func main() {
    out := bufio.NewWriterSize(os.Stdout, 20)
    // defer out.Flush() // commented for demonstration purpose. Uncomment this to finalize the flush.
    a := A{42}
    b, _ := json.MarshalIndent(a, "", "\t")
    out.Write(b)
    b = bytes.Replace(b, []byte("42"), []byte("666"), -1)
    out.Write(b)
}

不建议这样做,但是最终这是可能的。

我提供了一个缓冲的作家来演示其他人的答案和评论,不要忘记刷新它。