How can we read a json file as json object in golang

huangapple go评论81阅读模式
英文:

How can we read a json file as json object in golang

问题

我有一个存储在本地机器上的JSON文件。我需要将其读入一个变量,并循环遍历以获取JSON对象的值。如果我在使用ioutil.ReadFile方法读取文件后使用Marshal命令,它会输出一些数字。以下是我的几次尝试失败的情况:

尝试1:

plan, _ := ioutil.ReadFile(filename) // filename是要读取的JSON文件
var data interface{}
err := json.Unmarshal(plan, data)
if err != nil {
    log.Error("无法解组json", err)
}
fmt.Println(data)

它给了我以下错误:

time="2016-12-13T22:13:05-08:00" level=error msg="无法解组json json: Unmarshal(nil)"
<nil>

尝试2:我尝试将JSON值存储在一个结构体中,然后使用MarshalIndent

generatePlan, _ := json.MarshalIndent(plan, "", " ") // plan是指向结构体的指针
fmt.Println(string(generatePlan))

它给我输出的是字符串。但是,如果我将输出转换为字符串,那么我将无法将其作为JSON对象进行循环。

我们如何在golang中将JSON文件读取为JSON对象?是否有可能做到这一点?
非常感谢您的帮助!

英文:

I have a JSON file stored on the local machine. I need to read it in a variable and loop through it to fetch the JSON object values. If I use the Marshal command after reading the file using the ioutil.Readfile method, it gives some numbers as an output. These are my few failed attempts,

Attempt 1:

plan, _ := ioutil.ReadFile(filename) // filename is the JSON file to read
var data interface{}
err := json.Unmarshal(plan, data)
if err != nil {
		log.Error(&quot;Cannot unmarshal the json &quot;, err)
	  }
fmt.Println(data)

It gave me following error,

time=&quot;2016-12-13T22:13:05-08:00&quot; level=error msg=&quot;Cannot unmarshal the json json: Unmarshal(nil)&quot;
&lt;nil&gt;

Attempt 2: I tried to store the JSON values in a struct and then using MarshalIndent

generatePlan, _ := json.MarshalIndent(plan, &quot;&quot;, &quot; &quot;) // plan is a pointer to a struct
fmt.Println(string(generatePlan))

It give me the output as string. But if I cast the output to string then I won't be able to loop it as JSON object.

How can we read a JSON file as JSON object in golang? Is it possible to do that?
Any help is appreciated. Thanks in advance!

答案1

得分: 65

json.Unmarshal需要填充的值必须是一个指针。

根据GoDoc

Unmarshal解析JSON编码的数据,并将结果存储在v指向的值中。

因此,你需要执行以下操作:

plan, _ := ioutil.ReadFile(filename)
var data interface{}
err := json.Unmarshal(plan, &data)

你的错误(Unmarshal(nil))表明在读取文件时出现了一些问题,请检查ioutil.ReadFile返回的错误。

此外,请注意,在解组时使用空接口,你需要使用type assertion将其转换为Go原始类型。

为了将JSON解组为接口值,Unmarshal将以下类型之一存储在接口值中:

  • bool,用于JSON布尔值
  • float64,用于JSON数字
  • string,用于JSON字符串
  • []interface{},用于JSON数组
  • map[string]interface{},用于JSON对象
  • nil,用于JSON null

使用具体的结构体来填充你的JSON数据并使用Unmarshal是一种更好的方法。

英文:

The value to be populated by json.Unmarshal needs to be a pointer.

From GoDoc :

> Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v.

So you need to do the following :

plan, _ := ioutil.ReadFile(filename)
var data interface{}
err := json.Unmarshal(plan, &amp;data)

Your error (Unmarshal(nil)) indicates that there was some problem in reading the file , please check the error returned by ioutil.ReadFile


Also please note that when using an empty interface in unmarshal, you would need to use type assertion to get the underlying values as go primitive types.

> To unmarshal JSON into an interface value, Unmarshal stores one of
> these in the interface value:
>
> bool, for JSON booleans
> float64, for JSON numbers
> string, for JSON strings
> []interface{}, for JSON arrays
> map[string]interface{}, for JSON objects
> nil for JSON null

It is always a much better approach to use a concrete structure to populate your json using Unmarshal.

答案2

得分: 8

如果您在2022年看到这个消息,ioutil包已经被弃用。您仍然可以使用它,但可能会遇到烦人的错误。

相反,您可以使用os包。

someStruct := SomeStruct{} 	// 通过unmarshal捕获错误
fileBytes, _ := os.ReadFile(filename) 	
err := json.Unmarshal(fileBytes, spec) 

请注意,我特意忽略了os.ReadFile的错误,因为这样做也会导致json.Unmarshal出错,这只是为了举例说明。

英文:

If you're looking at this in 2022, the ioutil package has been deprecated. You can still use it but you'll get annoying errors.

Instead you can use the os package.

someStruct := SomeStruct{} 	// Read errors caught by unmarshal
fileBytes, _ := os.ReadFile(filename) 	
err := json.Unmarshal(fileBytes, spec) 

Note, I'm specifically ignoring the error from os.ReadFile since it will also cause an error in json.Unmarshal for the sake of the example.

huangapple
  • 本文由 发表于 2016年12月14日 13:48:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/41135686.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定