1.数据交换格式简介
1.简介
- 1.分布式系统
- 2.打包和解包操做
- 3.传输模式:
2.JSON数据格式
1.对象{key-value}形式
2.数组[{key-value}]
3.实例代码
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"strconv"
)
type Person struct {
Name string
Age int
Sex string
}
func writeJson(filename string) (err error) {
var person []*Person
for i := 0; i < 10; i++ {
p := &Person{
Name: "name" + strconv.Itoa(i),
Age: rand.Intn(100),
Sex: "Man",
}
person = append(person, p)
}
data, err := json.Marshal(person)
if err != nil {
fmt.Println("json marshal failed, err: ", err)
return
}
ioutil.WriteFile(filename, data, 0755)
return
}
func main() {
writeJson("./data.json")
}
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type Person struct {
Name string
Age int
Sex string
}
func writeStruct(filename string) (err error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println("json unmarshal failed, err: ", err)
return
}
var person []*Person
json.Unmarshal(data, &person)
fmt.Println(person)
return
}
func main() {
writeStruct("./data.json")
}
3.XML数据格式
1.简介
2.实例代码
<?xml version="1.0" encoding="UTF-8"?>
<dates version="1.0">
<date>
<id>1</id>
<name>JSON</name>
<abb>JavaScript Object Notation</abb>
</date>
<date>
<id>2</id>
<name>XML</name>
<abb>eXtensible Markup Language</abb>
</date>
<date>
<id>3</id>
<name>YAML</name>
<abb>Yet Another Markup Language</abb>
</date>
</dates>
package main
import (
"encoding/xml"
"fmt"
"io/ioutil"
)
type DateXml struct {
Version string `xml:"version,attr"`
Dates []Date `xml:"date"`
}
type Date struct {
Id string `xml:"id"`
Name string `xml:"name"`
Abb string `xml:"abb"`
}
func writeStruct() (err error) {
data, err := ioutil.ReadFile("./data.xml")
if err != nil {
fmt.Println("read xml failed, err: ", err)
return
}
var dataStruct DateXml
err = xml.Unmarshal(data, &dataStruct)
if err != nil {
fmt.Printf("unmarshal failed, err: %v", err)
}
fmt.Printf("%v", dataStruct)
return
}
func main() {
writeStruct()
}
/*
{1.0 [{1 JSON JavaScript Object Notation} {2 XML eXtensible Markup Language} {3 YAML Yet Another Markup Language}]}
*/
- 3.应用场景:配置文件以及
webservice,比如:soap协议
4.MSGPack数据格式
1.二进制的json协议
- 1.性能更快
- 2.更省空间
![]()
2.应用实战
- 1.
Marshal:序列化
- 2.
UnMarshal:反序列化
- 3.应用场景:Api通讯
- 安装第三方包
go get github.com/vmihailenco/msgpack
package main
import (
"fmt"
"github.com/vmihailenco/msgpack/v5"
"io/ioutil"
"math/rand"
"strconv"
)
type Person struct {
Name string
Age int
Sex string
}
func writeJson(filename string) (err error) {
var person []*Person
for i := 0; i < 10; i++ {
p := &Person{
Name: "name" + strconv.Itoa(i),
Age: rand.Intn(100),
Sex: "Man",
}
person = append(person, p)
}
data, err := msgpack.Marshal(person)
if err != nil {
fmt.Println("json marshal failed, err: ", err)
return
}
ioutil.WriteFile(filename, data, 0755)
return
}
func writeStruct(filename string) (err error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println("json unmarshal failed, err: ", err)
return
}
var person []*Person
msgpack.Unmarshal(data, &person)
fmt.Println(person)
return
}
func main() {
writeJson("./data.dat")
//writeStruct("./data.dat")
}
5.Protobuf数据格式
1.简介
- 1.
google推出的数据交换格式
- 2.二进制的
- 3.基于代码自动生成
2.Protobuf开发流程
- 1.
IDL编写
- 2.生成指定的语言代码
- 3.序列化和反序列化
![]()
3.Protobuf数据类型
1.枚举类型
enum EnumAllowingAlias {
UNKNOWN = 0;
STARTED = 1;
RUNNING = 2;
}
2.结构体类型
message Persion {
// 后面的数字表示标识符
int32 id = 1;
string name = 2;
// repeated 表示可以重复【数组】
// 可以有多个手机
repeated Phone phones = 3;
}
4.依赖安装
- 1.地址:
https://github.com/protocolbuffers/protobuf/releases
- 2.安装
protobuf编译器,解压后拷贝bin/protoc.exe到GOPATH/bin目录下
- 3.安装
golang代码插件:go get -u github.com/golang/protobuf/protoc-gen-go
5.生成.proto文件
- 1.编写
IDL:proto/person.proto
// 指定版本
// 注意:proto3与proto2的写法有些不同(proto3默认值为字段类型对应的零值,proto2需要使用default关键字来指明)
syntax = "proto3";
// 指定生成文件存储的路径,拼接`--go_out`指定的路径,即 ./address,和person.proto同级
option go_package = "/address";
// 指定等会文件生成出来的package
package address
// 手机类型
// 枚举类型第一个字段必须为0
enum PhoneType {
HOME = 0;
WORK = 1;
}
// 手机
message Phone {
// 类型 字段名
PhoneType type = 1;
string number = 2;
}
// 人
message Person {
int32 id = 1;
string name = 2;
// required 消息体中必填字段,不设置会导致编码异常(require在proto3中不用写,默认)
// optional 消息体中可选字段
// repeated 消息体中可重复字段,重复的值的顺序会被保留,在go中重复的会被定义为切片
repeated Phone phones = 3;
}
// 联系薄
message ConnectBook {
repeated Person persons = 1;
}
// 定义服务
service SearchService {
// rpc 服务的函数名 (传入参数—) 返回 (返回参数)
rpc Search (SearchRequest) returns (SearchResponse);
}
protoc --go_out=. ./person.proto
package main
import (
"dcpuffer/dcpuffer/proto/address"
"fmt"
"github.com/golang/protobuf/proto"
"io/ioutil"
)
func writeProto(filename string) (err error) {
var connectBook address.ConnectBook
for i := 0; i < 60; i++ {
p := &address.Person{
Id: int32(i),
Name: fmt.Sprintf("刘%d", i),
}
phone := &address.Phone{
Type: address.PhoneType_HOME,
Number: "15910827647",
}
p.Phones = append(p.Phones, phone)
connectBook.Persons = append(connectBook.Persons, p)
}
data, err := proto.Marshal(&connectBook)
if err != nil {
fmt.Println("marshal proto buf failed, err: ", err)
return
}
err = ioutil.WriteFile(filename, data, 0755)
if err != nil {
fmt.Println("write file failed, err: ", err)
return
}
return
}
func readProto(filename string) (err error) {
var connectBook address.ConnectBook
data, _ := ioutil.ReadFile(filename)
err = proto.Unmarshal(data, &connectBook)
if err != nil {
fmt.Println("read file failed, err: ", err)
}
fmt.Println(connectBook.String())
return
}
func main() {
// 序列化
//writeProto("./connectBook.dat")
// 反序列化
readProto("./connectBook.dat")
}