我是新手,所以不太了解语言特定的结构.
我的用例首先是在内存中读入包含换行分隔的JSON blob的输入文件.从这个JSON源的"数组",我想解组每个数组元素来处理它在golang中.预期的结构映射已经定义.
我通常喜欢一次读取所有行,所以如何在Golangioutil.ReadFile()
中如何将整个文件读入字符串变量?似乎是个不错的选择.并且json.Unmarshal
似乎将字节数组作为源.但是如果我使用的是ReadFile(),那么整个文件只有一个字节数组.我如何提取此字节数组的切片,以便跳过换行字节(作为分隔符),每个切片是那些JSON blob之一?我认为最好的技术是不做或最小化数据类型转换的技术.因为简单的hack就像将字节数组转换为字符串一样,将换行符分隔的字符串拆分为数组然后将每个字符串数组元素转换回字节以传递给json.Unmarshal.我更喜欢优化的方法但不确定如何解决go中的实现算法细节,可以在这里使用一些提示.
理想情况下,我希望事先完成预处理,这样我就不会从文件中处理JSON字节数组的内容,因为我正在遍历切片等等.而是我想预处理单字节数组从文件读取到一个字节数组切片数组,删除所有换行字节,每个切片是由换行符分隔的段.
使用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方法比其他方法使用更多内存(文件中每个字节一个字节加上每行一个切片标头).
因为解码器忽略了遵循JSON值的空格,所以这三种方法处理\ r \n行终止符.
除了将JSON字节解组为Go值所固有的方法之外,这些方法中没有任何数据转换.