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
,是否有更好的方法来执行此操作
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
满足这个接口。应用程序是读写的