Golang中JSON文件处理

Go语言编程系列文章

Go语言学习历程整理:

序号文章
1.👀Go 爬虫之CSDN博客信息

文章目录


前言

        JSON是一种比XML更轻量级的数据交换格式,易于阅读和编写的同时,也易于程序的解析和生成。此外,虽然JSON源于JS, 由于JSON采用了完全独立于语言的文本格式,采用键值的方式构建描述信息,因此逐渐成为较理想的、跨平台的、跨语言的数据交换格式。

        Go语言对JSON提供的很好的支持:GO语言内置encoding/json标准库。开发人员可以通过标准库函数轻松完成JSON数据格式的生成和解析工作。

        下面对JSON文件的生成和解析做一个简单介绍。


一、🔔将数据编码为JSON格式

        Go原因中可以使用 json.Marshal() 函数将一组数据进行JSON格式编码。它的原型如下:

func Marshal(v interface{}) ([]byte, error)

 接收任意类型的参数,并将其转换为json格式,最后通过byte切片的方式返回。

用法如下:

package main

import (
	"encoding/json"
	"fmt"
)

type Student struct {
	Name   string `json:"name"`
	Age    int    `json:"age"`
	Email  string `json:"email"`
	Wechat string `json:"wechat"`
}

func JsonMarshal() {
	xiaoMing := Student{
		Name:   "xiaoMing",
		Age:    23,
		Email:  "vip_13031075266@163.com",
		Wechat: "ssjjqq23",
	}

	fmt.Println(xiaoMing)

	data, _ := json.Marshal(xiaoMing)
	fmt.Printf("%s\n", data)
}

运行结果如下:

{"name":"xiaoMing","age":23,"email":"vip_13031075266@163.com","wechat":"ssjjqq23"}

在Go中, JSON转化前后的数据类型映射如下。
0️⃣ 布尔值转化为JSON后还是布尔类型。
1️⃣ 浮点数和整型会被转化为JSON里边的常规数字。
2️⃣ 字符串将以UTF-8编码转化输出为Unicode字符集的字符串。
3️⃣ 数组和切片会转化为JSON里边的数组,但[]byte类型的值将会被转化为 Base64 编码后
的字符串, slice类型的零值会被转化为 null。
4️⃣ 结构体会转化为JSON对象,并且只有结构体里边以大写字母开头的可被导出的字段才会
被转化输出,而这些可导出的字段会作为JSON对象的字符串索引。
5️⃣ 转化一个map类型的数据结构时,该数据的类型必须是 map[string]T(T可以是
encoding/json 包支持的任意数据类型)

二、🔔对JSON数据进行解码

        在Go中使用 json.Unmarshal()函数将JSON格式数据解码为Go中期望的数据结构。原型如下:

func Unmarshal(data []byte, v interface{}) error

data : json编码的数据信息

v : 解码后的Go中的数据结构

用法如下:

package main

import (
	"encoding/json"
	"fmt"
	"log"
)

type Student struct {
	Name   string `json:"name"`
	Age    int    `json:"age"`
	Email  string `json:"email"`
	Wechat string `json:"wechat"`
}
type Msg struct {
	MessageType string          `json:"message_type"`
	MessageBody json.RawMessage `json:"message_body"`
}

func JsonUnMarshal() {
	jsonData := []byte(`{"name":"xiaoMing","age":23,
	"email":"vip_13031075266@163.com","wechat":"ssjjqq23"}`)

	var xiaoMing Student
	err := json.Unmarshal(jsonData, &xiaoMing)
	if err != nil {
		log.Print(err)
	}
	fmt.Printf("%+v\n", xiaoMing)
}

运行结果如下:

{Name:xiaoMing Age:23 Email:vip_13031075266@163.com Wechat:ssjjqq23}

🍓🍓🍓注意:

如果JSON中的字段在Go的目标类型中没有,json.Unmarshal()函数会在解码过程中将其丢弃。因此可以实现从JSON格式中获取直接字段的数据信息。

三、🔔解码未知结构的JSON数据

        在使用 json.Unmarshal()函数解析JSON格式数据时,需要传入目标类型的对象地址,而对于位置结构的JSON数据,由于无法提前得知目标类型,因此需要特别说明

       不过,值得庆幸的是: Go中提供了接口类型。而接口是通用类型,可以表示任意类型的。因此面对位置结构的json数据时,我们可以通过传入一个接口类型的变量来完成数据的解析

        在解码JSON数据的过程中,JSON数据里面的元素转换原则如下:

✅  JSON中的布尔值将会转换为Go中的bool类型

✅  数值会被转换为Go中的float64类型

✅  字符串转换后还是string类型

✅  JSON数组会转换为[]interface{}类型

✅  JSON对象会转换为map[string]interface{}类型

✅  null值会转换为nil

常见使用方法如下:

func JsonUnMarshalUnknownJson() {
	info := []byte(`{"MESSAGE_type": "tcp_log",
	"message_body": {"time": 1629344853314, "sess_id": "0x611DD45400000001",
	"sport": 12378, "dport": 21, "sip": "10.43.80.78", "dip": "10.44.98.224",
	"smac": "30:9C:23:36:97:00", "dmac": "80:05:88:CA:54:16", "device_port_id": 1,
	"close_status": "FIN", "device_id": "200707014084", "data_type": 1,
	"interface_icon": "hahah", "network_protocol": 0, "transport_protocol": 6,
	"session_protocol": 0, "app_protocol": 10, "log_type": 1, "client_total_byte": 126,
	"client_total_pkt": 17, "server_total_byte": 437, "server_total_pkt": 19,
	"flow_start_time": 1629344852098, "flow_end_time": 1629344852315,
	"flow_duration": 217, "avg_pkt_byte": 0, "avg_pkt_num": 0,
	"total_byte": 563, "avg_pkt_size": 15, "avg_delay_time": 244,
	"retrans_pkt_num": 0}}`)

	var unknowInfo interface{}
	err := json.Unmarshal(info, &unknowInfo)
	if err != nil {
		fmt.Printf("json unmarshal error:%s\n", err)
		return
	}
	msg, ok := unknowInfo.(map[string]interface{})
	if ok {
		for k, v := range msg {
			switch v2 := v.(type) {
			case string:
				fmt.Println(k, "is string", v2)
			case int:
				fmt.Println(k, "is int", v2)
			case bool:
				fmt.Println(k, "is bool", v2)
			case []interface{}:
				fmt.Println(k, "is an array:")
				for i, iv := range v2 {
					fmt.Println(i, iv)
				}
			default:
				fmt.Println(k, "is another type!!!")
			}
		}
	}
}

总结

        文章主要说明了Go中对JSON格式的编码和解码的使用。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Go语言,Protocol Buffers(protobuf)和JSON是两种常用的数据序列化格式,它们可以帮助你在不同环境之间传输数据,比如服务间通信、持久化存储等。以下是关于它们互转的简单介绍: 1. Protocol Buffers (protobuf): - **protobuf**是由Google开发的一种高效的跨语言数据交换格式,使用.proto文件定义数据结构,然后用`protoc`编译器生成对应的Go代码,实现了数据结构和编码解码功能。 - 在Go,你可以使用`google/protobuf`包来处理protobuf数据,`pb.NewMessage()`创建一个新的protobuf实例,`Marshal()`和`Unmarshal()`方法分别用于序列化和反序列化。 2. JSON (JavaScript Object Notation): - **JSON**是一种轻量级的数据交换格式,易于人阅读和编写,也容易被机器解析和生成。Go语言的`encoding/json`包提供了处理JSON数据的功能。 - Go的`json.Marshal()`和`json.Unmarshal()`函数分别用于将Go数据结构编码为JSON字符串和从JSON字符串反序列化到Go结构体。 互转方法: - **从protobuf转JSON**: - 首先,使用`protoc`编译器生成Go代码,包含`json`标签的protobuf字段可以直接转换。 - 如果没有直接支持,可以手动将protobuf对象转换为map[string]interface{},然后使用`json.Marshal()`。 - **从JSON转protobuf**: - 使用`json.Unmarshal()`将JSON字符串解码成Go map或struct,然后构造protobuf对象,设置相应的字段值。 相关问题: 1. protoc编译器在Go如何使用? 2. 如何在protobuf添加`json`标签以支持JSON序列化? 3. 如果protobuf对象某些字段不需要JSON转换,如何处理
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叨陪鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值