清风徐来
Michael's Blog
Go解析JSON文件

在本教程中,我们将了解如何读取JSON文件或JSON HTTP响应并根据需要解析它们。 请输入图片描述 我们可以使用XML或JSON表示相同的信息,但JSON提供了一个优势,它更紧凑,并且在我的个人经验中,更具可读性。

JSON现在是最流行的数据格式,大多数RESTful API都会提供JSON响应。因此本文非常有用!

##Encoding/Json Package

我们将利用encoding / json标准库包来启动和运行。我强烈建议你在这里查看官方文档:Encoding / Json

##读取和解析JSON文件

user.json

{
  "users": [
    {
      "name": "Elliot",
      "type": "Reader",
      "age": 23,
      "social": {
        "facebook": "https://facebook.com",
        "twitter": "https://twitter.com"
      }
    },
    {
      "name": "Fraser",
      "type": "Author",
      "age": 17,
      "social": {
        "facebook": "https://facebook.com",
        "twitter": "https://twitter.com"
      }
    }
  ]
}

###读取JSON文件 使用os包来从我们的文件系统中打开users.json文件。打开文件后,我们将关闭文件(函数结束时执行defer后的关闭)。

jsonFile, err := os.Open("users.json")
if err != nil {
    fmt.Println(err)
}
fmt.Println("成功打开 users.json")
// 推迟关闭我们的jsonFile,以便稍后解析它
defer jsonFile.Close()

###用结构解析

我们可以用结构或是map[string]interface{}来解析users.json。我们用结构,上代码:

package main

import (
    "encoding/json"
)

// Users 结构
// 一个User数组
type Users struct {
    Users []User `json:"users"`
}

// User 结构,包含来Social结构
type User struct {
    Name   string `json:"name"`
    Type   string `json:"type"`
    Age    int    `json:"Age"`
    Social Social `json:"social"`
}

// Social 结构
type Social struct {
    Facebook string `json:"facebook"`
    Twitter  string `json:"twitter"`
}

##处理JSON(解组Unmarshal)

// 将我们打开的json文件作为字节数组读取.
byteValue, _ := ioutil.ReadAll(jsonFile)

// 初始化我们的Users数组
var users Users

// 将json的内容,byte Array解组为上面定义的'users'
json.Unmarshal(byteValue, &users)

// 遍历数组中的每个用户,输出user的Type, name和脸书的url
for i := 0; i < len(users.Users); i++ {
    fmt.Println("User Type: " + users.Users[i].Type)
    fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))
    fmt.Println("User Name: " + users.Users[i].Name)
    fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)
}

##使用非结构化数据 我们也可以用interface{}来读取JSON数据

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
)

func main() {
    jsonFile, err := os.Open("users.json")
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("成功打开 users.json")
    defer jsonFile.Close()

    byteValue, _ := ioutil.ReadAll(jsonFile)

    var result map[string]interface{}
    json.Unmarshal([]byte(byteValue), &result)

    fmt.Println(result["users"])

}

结果是输出map的格式:

$ go run main.go
成功打开 users.json
[map[age:23 name:Elliot social:map[facebook:https://facebook.com twitter:https://twitter.com] type:Reader] map[age:17 name:Fraser social:map[facebook:https://facebook.com twitter:https://twitter.com] type:Author]]

ps:通常都是知道返回的数据的结构的,所以一般建议尝试定义结构去解组。

##小结用结构解组的全部代码

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
)

// Users 结构
// 一个User数组
type Users struct {
	Users []User `json:"users"`
}

// User 结构,包含来Social结构
type User struct {
	Name   string `json:"name"`
	Type   string `json:"type"`
	Age    int    `json:"Age"`
	Social Social `json:"social"`
}

// Social 结构
type Social struct {
	Facebook string `json:"facebook"`
	Twitter  string `json:"twitter"`
}

func main() {
	jsonFile, err := os.Open("users.json")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("成功打开 users.json")
	defer jsonFile.Close()

	// 将我们打开的json文件作为字节数组读取.
	byteValue, _ := ioutil.ReadAll(jsonFile)

	// 初始化我们的Users数组
	var users Users

	// 将json的内容,byte Array解组为上面定义的'users'
	json.Unmarshal(byteValue, &users)

	// 遍历数组中的每个用户,输出user的Type, name和脸书的url
	for i := 0; i < len(users.Users); i++ {
		fmt.Println("User Type: " + users.Users[i].Type)
		fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))
		fmt.Println("User Name: " + users.Users[i].Name)
		fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)
	}
}

执行:

$ go run main.go
成功打开 users.json
User Type: Reader
User Age: 23
User Name: Elliot
Facebook Url: https://facebook.com
User Type: Author
User Age: 17
User Name: Fraser
Facebook Url: https://facebook.com

最后修改于 2019-07-30