为了账号安全,请及时绑定邮箱和手机立即绑定

io.Reader 可以接受文件描述符吗?“JSON 输入意外结束”

io.Reader 可以接受文件描述符吗?“JSON 输入意外结束”

Go
狐的传说 2023-07-10 14:45:27
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
 }


查看完整回答
反对 回复 2023-07-10
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信