json.Unmarshal
将打开的文件描述符从 os.Create() 传递到接受类型 io.Reader 并运行 io.Copy(b.Bytes(), reader) 的函数后,有效 JSON 失败
下面代码块中的方法是否Read()
正确实现?io.Reader
包装该Read
方法,但会向其传递一个打开的文件描述符,将文件读取为字节,从而允许 io.Copy(b.Bytes(), reader) 将数据复制到 var b 中?
有没有更好的方法来做到这一点而不使用ioutil.ReadAll
?
已验证 JSON 完全有效。使用 jq 和 3 个在线 JSON 验证器进行验证。
验证数据实际上已通过另一个实现 io.Write 的函数成功写入文件。
已验证ioutil.ReadAll
可以将 JSON 读取为字节,因此我认为所使用的方法实施不正确。
** 这不是我的代码,我正在对其他人编写的代码进行故障排除,但其他人无法回答任何问题 **
我有一个 json 文件collected_data.json
。
该文件是使用 os.Create 创建的
file, err := os.Create("/var/log/collected_data.json")
配置了一个结构,将其设置file
为DataStore
:
profiler := &collectors.SystemProfiler{
DataStore: file,
NetworkInterfaces: interfaces,
ApiURL: *apiURL,
RunOnce: *runOnce,
SysTag: *sysTag,
}
然后我们运行一个Gather()方法。
err = profiler.Send(output)
if err != nil {
log.Error(err)
}
该Send()方法实现了 SystemProfiler 结构:
func (s *SystemProfiler) Send(profile *SystemProfile) error {...}
到此为止,一切工作正常,直到我们尝试从 读取和解组数据的代码部分/var/log/collected_data.json。
在此Send()方法中,我们尝试在两种情况下读取文件/var/log/collected_data.json。
第一,如果文件不为空,我们读取该文件,并用它做一些事情(此处未显示)。
data, err := store.Read(s.DataStore)
if err != nil {
log.Print("I couldn't read the datastore")
return err
}
第二,如果文件不为空,我们将数据写入文件,然后立即将其读回并 Unmarshal 以满足稍后在reflect.DeepEqual数据比较和写入文件的数据之间进行比较的函数。
在这两种情况下,该Read()方法都会返回“Unexpected end of JSON input”,并且文件中包含有效的 JSON /var/log/collected_data.json。用于写入数据的方法工作得很好。
{"level":"info","msg":"I couldn't read the datastore","time":"2019-08-02T02:26:42-04:00"}
{"level":"error","msg":"unexpected end of JSON input","time":"2019-08-02T02:26:42-04:00"}
该Read()方法如下所示:
// Read reads JSON data from an io.Reader
func Read(reader io.Reader) (interface{}, error) {
var data interface{}
var b bytes.Buffer
io.Copy(&b, reader)
err := json.Unmarshal(b.Bytes(), &data)
if err != nil {
return nil, err
}
return data, nil
}
预期成绩:
有效的 JSON 从 io.Reader 类型的 reader 复制到 bytes.Buffer 类型的 b,成功解组并返回。
实际结果:{"level":"error","msg":"JSON 输入意外结束","time":"2019-08-02T02:26:42-04:00"}
暮色呼如
相关分类