Home  >  Article  >  Backend Development  >  json.Unmarshal file data is valid, but json.NewDecoder().Decode() is invalid

json.Unmarshal file data is valid, but json.NewDecoder().Decode() is invalid

WBOY
WBOYforward
2024-02-09 12:15:31822browse

json.Unmarshal 文件数据有效,但 json.NewDecoder().Decode() 无效

php editor Strawberry will introduce you to a problem about JSON parsing. Sometimes we encounter a situation where using json.Unmarshal to parse file data is effective, but using json.NewDecoder().Decode() is not effective. This problem may occur in the code logic or data format. Below we will analyze the possible causes in detail and provide solutions.

Question content

The following correctly unmarshals the structure:

func foo() {
  d, err := os.readfile("file.json")

  var t t
  if err := json.unmarshal(d, &t); err != nil {
    panic(err)
  }
}

But this doesn't work and throws a bunch of classic json parsing errors, i.e. eof, unexpected token 't', etc.

func foo() {
  f, err := os.open("file.json")
  
  var t t
  if err := json.newdecoder(f).decode(&t); err != nil {
    panic(err)
  }
}

Do you know why? os.file or []byte is used in two goroutines at the same time. The json structure is as follows (some fields are omitted):

{
  "data": [
    {
      "field": "stuff",
      "num": 123,
    },
    ...
  ]
}

Solution

os.File or []byte Use in two goroutines at the same time...

This is where the problem lies. os.File has an internal file pointer where the next read occurs. If two unrelated entities continue to read data from it, they may not read overlapping data. Bytes read by the first entity are not repeated in the second entity.

Additionally, os.File is not safe for concurrent use (the documentation does not explicitly state that it is safe): calling its methods from multiple concurrent goroutines may cause data races.

When you pass []byte to multiple functions/goroutines that "read from", there are no shared pointers or index variables. Each function/goroutine will maintain its index separately, and it is OK to read variables from multiple goroutines (in this case fields of the slice header and slice elements).

The above is the detailed content of json.Unmarshal file data is valid, but json.NewDecoder().Decode() is invalid. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete