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

问题描述 投票:-2回答:2

我将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

go
2个回答
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的连续值以及磁盘的速度。


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)
}

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

我包括一个缓冲的作家,用于演示其他人的答案和评论,不要忘记冲洗它。

© www.soinside.com 2019 - 2024. All rights reserved.