1. 数据格式

1.1.1. 数据格式介绍

  • 是系统中数据交互不可缺少的内容
  • 这里主要介绍JSON、XML、MSGPack

1.1.2. JSON

  • json是完全独立于语言的文本格式,是k-v的形式 name:zs
  • 应用场景:前后端交互,系统间数据交互

数据格式 - 图1

  • json使用go语言内置的encoding/json 标准库
  • 编码json使用json.Marshal()函数可以对一组数据进行JSON格式的编码
  1. func Marshal(v interface{}) ([]byte, error)

示例过结构体生成json

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Person struct {
  7. Name string
  8. Hobby string
  9. }
  10. func main() {
  11. p := Person{"5lmh.com", "女"}
  12. // 编码json
  13. b, err := json.Marshal(p)
  14. if err != nil {
  15. fmt.Println("json err ", err)
  16. }
  17. fmt.Println(string(b))
  18. // 格式化输出
  19. b, err = json.MarshalIndent(p, "", " ")
  20. if err != nil {
  21. fmt.Println("json err ", err)
  22. }
  23. fmt.Println(string(b))
  24. }

struct tag

  1. type Person struct {
  2. //"-"是忽略的意思
  3. Name string `json:"-"`
  4. Hobby string `json:"hobby" `
  5. }

示例通过map生成json

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. func main() {
  7. student := make(map[string]interface{})
  8. student["name"] = "5lmh.com"
  9. student["age"] = 18
  10. student["sex"] = "man"
  11. b, err := json.Marshal(student)
  12. if err != nil {
  13. fmt.Println(err)
  14. }
  15. fmt.Println(b)
  16. }
  • 解码json使用json.Unmarshal()函数可以对一组数据进行JSON格式的解码
  1. func Unmarshal(data []byte, v interface{}) error

示例解析到结构体

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. type Person struct {
  7. Age int `json:"age,string"`
  8. Name string `json:"name"`
  9. Niubility bool `json:"niubility"`
  10. }
  11. func main() {
  12. // 假数据
  13. b := []byte(`{"age":"18","name":"5lmh.com","marry":false}`)
  14. var p Person
  15. err := json.Unmarshal(b, &p)
  16. if err != nil {
  17. fmt.Println(err)
  18. }
  19. fmt.Println(p)
  20. }

示例解析到interface

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. )
  6. func main() {
  7. // 假数据
  8. // int和float64都当float64
  9. b := []byte(`{"age":1.3,"name":"5lmh.com","marry":false}`)
  10. // 声明接口
  11. var i interface{}
  12. err := json.Unmarshal(b, &i)
  13. if err != nil {
  14. fmt.Println(err)
  15. }
  16. // 自动转到map
  17. fmt.Println(i)
  18. // 可以判断类型
  19. m := i.(map[string]interface{})
  20. for k, v := range m {
  21. switch vv := v.(type) {
  22. case float64:
  23. fmt.Println(k, "是float64类型", vv)
  24. case string:
  25. fmt.Println(k, "是string类型", vv)
  26. default:
  27. fmt.Println("其他")
  28. }
  29. }
  30. }

1.1.3. XML

  • 是可扩展标记语言,包含声明、根标签、子元素和属性
  • 应用场景:配置文件以及webService

示例:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <servers version="1">
  3. <server>
  4. <serverName>Shanghai_VPN</serverName>
  5. <serverIP>127.0.0.1</serverIP>
  6. </server>
  7. <server>
  8. <serverName>Beijing_VPN</serverName>
  9. <serverIP>127.0.0.2</serverIP>
  10. </server>
  11. </servers>
  1. package main
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "io/ioutil"
  6. )
  7. // 抽取单个server对象
  8. type Server struct {
  9. ServerName string `xml:"serverName"`
  10. ServerIP string `xml:"serverIP"`
  11. }
  12. type Servers struct {
  13. Name xml.Name `xml:"servers"`
  14. Version int `xml:"version"`
  15. Servers []Server `xml:"server"`
  16. }
  17. func main() {
  18. data, err := ioutil.ReadFile("D:/my.xml")
  19. if err != nil {
  20. fmt.Println(err)
  21. return
  22. }
  23. var servers Servers
  24. err = xml.Unmarshal(data, &servers)
  25. if err != nil {
  26. fmt.Println(err)
  27. return
  28. }
  29. fmt.Printf("xml: %#v\n", servers)
  30. }

1.1.4. MSGPack

  • MSGPack是二进制的json,性能更快,更省空间
  • 需要安装第三方包:go get -u github.com/vmihailenco/msgpack
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/vmihailenco/msgpack"
  5. "io/ioutil"
  6. "math/rand"
  7. )
  8. type Person struct {
  9. Name string
  10. Age int
  11. Sex string
  12. }
  13. // 二进制写出
  14. func writerJson(filename string) (err error) {
  15. var persons []*Person
  16. // 假数据
  17. for i := 0; i < 10; i++ {
  18. p := &Person{
  19. Name: fmt.Sprintf("name%d", i),
  20. Age: rand.Intn(100),
  21. Sex: "male",
  22. }
  23. persons = append(persons, p)
  24. }
  25. // 二进制json序列化
  26. data, err := msgpack.Marshal(persons)
  27. if err != nil {
  28. fmt.Println(err)
  29. return
  30. }
  31. err = ioutil.WriteFile(filename, data, 0666)
  32. if err != nil {
  33. fmt.Println(err)
  34. return
  35. }
  36. return
  37. }
  38. // 二进制读取
  39. func readJson(filename string) (err error) {
  40. var persons []*Person
  41. // 读文件
  42. data, err := ioutil.ReadFile(filename)
  43. if err != nil {
  44. fmt.Println(err)
  45. return
  46. }
  47. // 反序列化
  48. err = msgpack.Unmarshal(data, &persons)
  49. if err != nil {
  50. fmt.Println(err)
  51. return
  52. }
  53. for _, v := range persons {
  54. fmt.Printf("%#v\n", v)
  55. }
  56. return
  57. }
  58. func main() {
  59. //err := writerJson("D:/person.dat")
  60. //if err != nil {
  61. // fmt.Println(err)
  62. // return
  63. //}
  64. err := readJson("D:/person.dat")
  65. if err != nil {
  66. fmt.Println(err)
  67. return
  68. }
  69. }