gpt4 book ai didi

json - 不要将不需要的 JSON 键值读入内存

转载 作者:IT王子 更新时间:2023-10-29 01:11:14 26 4
gpt4 key购买 nike

我有一个包含单个字段的 JSON 文件,当加载到内存中时,该文件占用巨大 的空间。其他字段是合理的,但我尽量注意不要加载该特定字段,除非我绝对必须这样做。

{
"Field1": "value1",
"Field2": "value2",
"Field3": "a very very long string that potentially takes a few GB of memory"
}

将该文件读入内存时,我想忽略 Field3(因为加载它可能会使我的应用程序崩溃)。这里有一些代码,我认为这样做是因为它使用 io 流,而不是将 []byte 类型传递给 Unmarshal 命令。

package main

import (
"encoding/json"
"os"
)

func main() {
type MyStruct struct {
Field1 string
Field2 string
}
fi, err := os.Open("myJSONFile.json")
if err != nil {
os.Exit(2)
}
// create an instance and populate
var mystruct MyStruct
err = json.NewDecoder(fi).Decode(&mystruct)
if err != nil {
os.Exit(2)
}
// do some other stuff
}

问题是内置的 json.Decoder 类型在丢弃与 struct 的字段(正如之前在 StackOverflow 上指出的那样:link)。

有没有什么方法可以在不将整个 JSON 对象保存在内存中的情况下在 Go 中解码 JSON?

最佳答案

您可以编写一个自定义的 io.Reader 并将其提供给 json.Decoder,这将预读您的 json 文件并跳过该特定字段。

另一种选择是编写自己的解码器,更加复杂和困惑。

//edit 这似乎是一个有趣的练习,所以这里是:

type IgnoreField struct {
io.Reader
Field string
buf bytes.Buffer
}

func NewIgnoreField(r io.Reader, field string) *IgnoreField {
return &IgnoreField{
Reader: r,
Field: field,
}
}
func (iF *IgnoreField) Read(p []byte) (n int, err error) {
if n, err = iF.Reader.Read(p); err != nil {
return
}
s := string(p)
fl := `"` + iF.Field + `"`
if i := strings.Index(s, fl); i != -1 {
l := strings.LastIndex(s[0:i], ",")
if l == -1 {
l = i
}
iF.buf.WriteString(s[0:l])

s = s[i+1+len(fl):]
i = strings.Index(s, `"`)
if i != -1 {
s = s[i+1:]
}
for {
i = strings.Index(s, `"`) //end quote
if i != -1 {
s = s[i+1:]
fmt.Println("Skipped")
break
} else {
if n, err = iF.Reader.Read(p); err != nil {
return
}
s = string(p)
}
}
iF.buf.WriteString(s)
}
ln := iF.buf.Len()
if ln >= len(p) {
tmp := iF.buf.Bytes()
iF.buf.Reset()
copy(p, tmp[0:len(p)])
iF.buf.Write(p[len(p):])
ln = len(p)
} else {
copy(p, iF.buf.Bytes())
iF.buf.Reset()
}
return ln, nil
}

func main() {
type MyStruct struct {
Field1 string
Field2 string
}
fi, err := os.Open("myJSONFile.json")
if err != nil {
os.Exit(2)
}
// create an instance and populate
var mystruct MyStruct
err := json.NewDecoder(NewIgnoreField(fi, "Field3")).Decode(&mystruct)
if err != nil {
fmt.Println(err)
}
fmt.Println(mystruct)
}

playground

关于json - 不要将不需要的 JSON 键值读入内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25002575/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com