Go io.Reader可以接受文件描述符吗&引用;JSON输入意外结束“;

Go io.Reader可以接受文件描述符吗&引用;JSON输入意外结束“;,go,Go,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是否完全有

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文件
    收集的数据.json

    该文件是使用os.Create创建的

    文件,err:=os.Create(“/var/log/collected_data.json”)
    
    配置了一个结构,将
    文件
    设置为
    数据存储

    profiler:=&collectors.SystemProfiler{
    数据存储:文件,
    网络接口:接口,
    ApiURL:*ApiURL,
    RunOnce:*RunOnce,
    SysTag:*SysTag,
    }
    
    然后我们运行一个
    Gather()
    方法

    err=profiler.Send(输出)
    如果出错!=零{
    日志错误(err)
    }
    
    Send()
    方法实现SystemProfiler结构:

    func(s*SystemProfiler)发送(profile*SystemProfile)错误{…}
    
    到了这一点,一切都很正常,直到我们尝试从
    /var/log/collected_data.json
    读取和解压数据的代码部分

    在这个
    Send()
    方法中,我们尝试在两种情况下读取文件
    /var/log/collected_data.json

    首先,如果文件不是空的,我们读取文件,并对其进行处理(此处未显示)

    data,err:=store.Read(s.DataStore)
    如果出错!=零{
    打印(“我无法读取数据存储”)
    返回错误
    }
    
    第二,如果文件不是空的,我们将数据写入文件,然后立即将其读回并解组,以满足后面的函数,该函数在比较的数据和写入文件的数据之间执行
    reflect.DeepEqual

    在这两种情况下,
    Read()。用于写入数据的方法工作得很好

    {"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从io.Reader读取JSON数据
    func Read(读卡器io.reader)(接口{},错误){
    变量数据接口{}
    VARBytes.Buffer
    io.复制(&b,读卡器)
    err:=json.Unmarshal(b.Bytes(),&data)
    如果错误!=零{
    返回零,错误
    }
    返回数据,无
    }
    
    预期成果:

    有效的JSON从io.reader类型的读卡器复制到bytes.Buffer类型的b,成功地取消了对其的签名,并返回

    实际结果: {“级别”:“错误”,“消息”:“JSON输入意外结束”,“时间”:“2019-08-02T02:26:42-04:00”}

    要回答评论中提出的问题,以下是
    Send()
    函数中的代码块:

    var存储配置文件系统配置文件
    检查:=store.IsEmpty(s.DataStore)
    如果检查==false{
    log.Print(“数据存储存在”)
    //如果存储了数据,请读取它
    数据,错误:=store.Read(s.DataStore)
    如果错误!=零{
    返回错误
    }
    //var tmp系统配置文件
    err=mapstructure.Decode(数据和存储配置文件)
    如果错误!=零{
    返回错误
    }
    }否则{
    log.Print(“数据存储不存在”)
    //如果数据存储为空,则向其写入
    错误:=store.Write(s.DataStore,profile)
    如果错误!=零{
    返回错误
    }
    数据,错误:=store.Read(s.DataStore)
    如果错误!=零{
    打印(“我无法读取数据存储”)
    返回错误
    }
    err=mapstructure.Decode(数据和存储配置文件)
    如果错误!=零{
    Print(“我无法将json解码为映射”)
    返回错误
    }
    body,err:=json.Marshal(概要文件)
    如果错误!=零{
    返回错误
    }
    _,err=client.Post(s.apirl,“application/json”,bytes.NewBuffer(body))//TODO:在此处处理来自API的响应
    log.Print(client.LogString())
    }
    如果!reflect.DeepEqual(storedProfile、profile){
    //如果数据存储中的内容与收集的内容不同,
    //将最近收集的数据写入数据存储并发送到API
    store.Write(s.DataStore,profile)
    body,err:=json.Marshal(概要文件)
    如果错误!=零{
    返回错误
    }
    _,err=client.Post(s.apirl,“application/json”,bytes.NewBuffer(body))//TODO:在此处处理来自API的响应
    如果错误!=零{
    返回错误
    }
    log.Print(client.LogString())
    }
    
    这个问题的答案是肯定的。
    *os.File
    可以用作
    io.Reader

    问题是,应用程序将数据写入文件,然后尝试从文件中读取相同的数据,而不查找数据写入的位置

    通过在调用store.Write之后和调用store.Read之前添加以下代码来修复此问题

     if _, err := s.DataStore.Seek(io.SeekStart, 0); err != nil {
         return err
     }
    

    io.Reader
    不“接受”任何内容,也不“包装”任何方法。它是一个接口,
    *os.File
    满足这个接口。应用程序是读写的