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.Readerfunc 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"}
1 回答
暮色呼如
TA贡献1853条经验 获得超9个赞
问题的答案是肯定的。An*os.File
可以用作io.Reader
.
问题在于应用程序将数据写入文件,然后尝试从文件中读取相同的数据,而不查找数据写入的位置。
通过在调用 store.Write 之后和调用 store.Read 之前添加以下代码来解决此问题。
if _, err := s.DataStore.Seek(io.SeekStart, 0); err != nil { return err }
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报
0/150
提交
取消