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.
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, }, ... ] }
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!