Home > Backend Development > Golang > 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
Release: 2024-02-09 12:15:31
forward
846 people have browsed it

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)
  }
}
Copy after login

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)
  }
}
Copy after login

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,
    },
    ...
  ]
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template