go - 将换行符分隔的 JSON blob 的整个文件读取到内存中,并在 golang 中使用最少的转换量解码每个 blob?

标签 go bytearray

我是新手,所以对特定于语言的结构了解不多。

我的用例是首先将包含以换行符分隔的 JSON blob 的输入文件读入内存。从这个 JSON 源“数组”中,我想解码每个数组元素以在 golang 中处理它。预期的结构映射已经定义。

我通常喜欢一次读取所有行,因此 ioutil.ReadFile()How can I read a whole file into a string variable in Golang? 中所述似乎是个不错的选择。而 json.Unmarshal 似乎以字节数组为源。但是,如果我使用 ReadFile(),则整个文件只有一个字节数组。我如何提取此字节数组的 slice ,以便跳过换行符字节(作为分隔符)并且每个 slice 都是那些 JSON blob 之一?我假设最好的技术是不进行或最小化数据类型转换的技术。由于简单的 hack 类似于将字节数组转换为字符串,将换行符分隔的字符串拆分为数组,然后将每个字符串数组元素转换回字节以传递给 json.Unmarshal。我更喜欢优化方法,但不确定如何处理 go 中的实现算法细节,可以在这里使用一些提示。

理想情况下,我希望预先完成预处理,这样我就不会在遍历 slice 等时处理文件中的 JSON 字节数组的内容。相反,我想预处理单字节数组从文件读入字节数组 slice 数组,删除所有换行字节,每个 slice 都是由换行符分隔的段。

最佳答案

使用bufio.Scanner一次读一行:

 f, err := os.Open(fname)
 if err != nil {
     // handle error
 }
 s := bufio.NewScanner(f)
 for s.Scan() {
    var v ValueTypeToUnmarshalTo
    if err := json.Unmarshal(s.Bytes(), &v); err != nil {
       //handle error
    }
    // do something with v
}
if s.Err() != nil {
    // handle scan error
}

或使用 ioutil.ReadFile 吞噬整个文件并 bytes.Split将文件分成几行:

 p, err := ioutil.ReadFile(fname)
 if err != nil {
    // handle error
 }
 for _, line := range bytes.Split(p, []byte{'\n'}) {
    var v ValueTypeToUnmarshalTo
    if err := json.Unmarshal(line, &v); err != nil {
       //handle error
    }
    // do something with v
 }

或使用 json.Decoder内置流功能,可从文件中读取多个值:

 f, err := os.Open(fname)
 if err != nil {
    // handle error
 }
 d := json.NewDecoder(f)
 for {
    var v ValueTypeToUnmarshalTo
    if err := d.Decode(&v); err == io.EOF {
       break // done decoding file
    } else if err != nil {
       // handle error
    }
    // do something with v
}

Run the code on the playground

ioutil.ReadFile 方法比其他方法使用更多的内存(文件中每个字节一个字节加上每行一个 slice header )。

因为解码器会忽略 JSON 值后面的空格,所以这三种方法都会处理\r\n 行终止符。

除了将 JSON 字节解码为 Go 值所固有的那些方法之外,这些方法中的任何一种都没有数据转换。

关于go - 将换行符分隔的 JSON blob 的整个文件读取到内存中,并在 golang 中使用最少的转换量解码每个 blob?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34388083/

相关文章:

sqlite - Android 中的 ByteArray 到 SQLite

mysql - Golang 将参数传递给 gorilla 路由器

go - OBJ 渲染不正确的纹理坐标

戈朗。重构||图案||任何解决方案

c++ - Qt4 : write QByteArray to file with filename?

actionscript-3 - 在不更改音调的情况下动态更改as3中声音的播放速度

go - 如何将参数正确传递给系统调用(git)?

go - NaN 是 golang 中的可比较类型吗?

java - 图像到字节数组到字符串(反之亦然)

java - 将 Document 对象转换为 Byte[]