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 關注
- 136 瀏覽
添加回答
舉報
0/150
提交
取消