文件操作

文件的基本介绍

  1. 文件是数据源(保存数据的地方)的一种,比如大家经常使用的 word 文档,txt 文件,excel 文件…都是文件。
  2. 文件最主要的作用就是保存数据,它既可以保存一张图片,也可以保持视频,声音…。
  3. 文件在程序中是以流的形式来操作的。
    • 流:数据在数据源(文件)和程序(内存)之间经历的路径。
    • 输入流:数据从数据源(文件)道程序(内存)的路径 —> 读文件
    • 输出流:数据从程序(内存)到数据源(文件)的路径。—> 写文件
  4. os.File 封装所有文件相关操作,File 是一个结构体。

    常用的文件操作函数和方法

  5. 打开一个文件进行读操作:

    1. os.Open(name string)(*File, error)
  6. 关闭一个文件:

    1. File.Close()
  7. 打开和关闭文件相关案例 ```go package main

import ( “fmt” “os” )

func main() {

  1. // 打开文件
  2. // 概念说明:file 的叫法
  3. //1. file 叫 file 对象
  4. //2. file 叫 file 指针
  5. //3. file 叫 file 文件句柄
  6. file, err := os.Open("d:/test.txt")
  7. if err != nil {
  8. fmt.Println("open file error: ", err)
  9. }
  10. //输出下文件,看看文件是什么
  11. fmt.Printf("file = %v\n", file)
  12. //关闭文件
  13. err = file.Close()
  14. if err != nil {
  15. fmt.Println("close file error: ", err)
  16. }

}

  1. 4. 其他的函数和方法在案例讲解
  2. <a name="7cf8ef7d"></a>
  3. ## 读文件操作应用实例
  4. 1. 读取文件的内容并显示在终端(带缓存区的方式),使用os.OpenFile.Closebufio.NewReader(),reader.Readstring 函数和方法。
  5. ```go
  6. package main
  7. import (
  8. "bufio"
  9. "fmt"
  10. "io"
  11. "os"
  12. )
  13. func main() {
  14. // 打开文件
  15. // 概念说明:file 的叫法
  16. //1. file 叫 file 对象
  17. //2. file 叫 file 指针
  18. //3. file 叫 file 文件句柄
  19. file, err := os.Open("/Users/mac/Desktop/Linux/phonelist.txt")
  20. if err != nil {
  21. fmt.Println("open file error: ", err)
  22. }
  23. //当函数退出时,要及时的关闭file
  24. defer file.Close() //要及时关闭 file 句柄,否则会有内存泄漏
  25. //创建一个 *Reader,是带缓冲的
  26. /*
  27. const(
  28. defaultBufSize = 4096 //默认的缓冲区为 4096
  29. )
  30. */
  31. reader := bufio.NewReader(file)
  32. //循环的读取文件内容
  33. for {
  34. str, err := reader.ReadString('\n') // 读到一个换行就结束
  35. if err == io.EOF {
  36. //io.EOF 表示文件末尾
  37. break
  38. }
  39. //输出内容
  40. fmt.Print(str)
  41. }
  42. fmt.Println("文件读取结束...")
  43. }
  1. 读取文件的内容并显示在终端(使用 ioutil 一次将整个文件读入到内存中),这种方式适用于文件不大的情况。相关方法核函数(ioutil.ReadFile)。 ```go package main

import ( “fmt” “io/ioutil” )

func main() { //使用 ioutil.ReadFile 一次性将文件读取到位 file := “/Users/mac/Desktop/Linux/phonelist.txt” content, err := ioutil.ReadFile(file) if err != nil { fmt.Println(“read file err: “,err) } //把读取到的内容显示到终端 fmt.Println(string(content)) //[]byte

  1. //因为,我们没有显式的 open文件,因此也不需要显式的 close 文件
  2. //因为,文件的 open 和 close 被封装到 ReadFile 函数内部

}

  1. <a name="31ee2e79"></a>
  2. ## 写文件操作应用实例
  3. <a name="f72dd4a6"></a>
  4. ### 基本介绍
  5. 1. func OpenFile(name string, flag int, perm FileMode)(file *File, err error)
  6. 1. 说明
  7. - os.OpenFile是一个更一般性的文件打开函数,它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。
  8. - 如果操作成功,返回的文件对象可用于 I/O 。如果出错,错误底层类型是 *PathError 。
  9. <a name="261f947c"></a>
  10. ### 基本应用实例-方式一
  11. 1. 创建一个新文件,写入内容 5 句 "hello,Gardon"
  12. ```go
  13. package main
  14. import (
  15. "bufio"
  16. "fmt"
  17. "os"
  18. )
  19. func main() {
  20. //创建一个新文件,写入内容5句"hello,Gordon"
  21. //1. 打开文件
  22. filePath := "/Users/mac/Desktop/Linux/print.txt"
  23. file, err := os.OpenFile(filePath, os.O_WRONLY | os.O_CREATE, 0755)
  24. if err != nil {
  25. fmt.Println("open file error: ", err)
  26. return
  27. }
  28. //及时关闭 file 句柄
  29. defer func() {
  30. err = file.Close()
  31. if err != nil {
  32. fmt.Println("close file error: ", err)
  33. }
  34. }()
  35. //准备写入5句"hello,Gordon"
  36. str := "hello,Gordon\n"
  37. //写入时,使用带缓存的 *Writer
  38. writer := bufio.NewWriter(file)
  39. for i:=0; i < 5; i++ {
  40. _, err = writer.WriteString(str)
  41. if err != nil {
  42. fmt.Println("write file error: ", err)
  43. }
  44. }
  45. /*
  46. 因为 writer 是带缓存,因此在调用 WriteString 方法时,其实内容是先写入缓存的,
  47. 所以需要调用 flush() 方法将缓存的内容真正写入到文件中,否则文件中会没有数据
  48. */
  49. err = writer.Flush()
  50. if err != nil {
  51. fmt.Println("flush error: ", err)
  52. }
  53. }
  1. 打开一个存在的文件,将原来的内容覆盖成新的内容 10 句 “你好,尚硅谷!” ```go package main

import ( “bufio” “fmt” “os” )

func main() { //打开一个存在的文件,将原来的内容覆盖成新的内容10句“你好,尚硅谷!” filePath := “/Users/mac/Desktop/Linux/print.txt” file, err := os.OpenFile(filePath, os.O_TRUNC | os.O_WRONLY, 0755) if err != nil { fmt.Println(“open file error: “, err) return }

  1. //及时关闭 file 句柄
  2. defer func() {
  3. err = file.Close()
  4. if err != nil {
  5. fmt.Println("close file error: ", err)
  6. }
  7. }()
  8. //准备写入10句"你好,尚硅谷!"
  9. str := "你好,尚硅谷!\r\n"
  10. //写入时,使用带缓存的 *Writer
  11. writer := bufio.NewWriter(file)
  12. for i:=0; i< 10; i++ {
  13. _, err = writer.WriteString(str)
  14. if err != nil {
  15. fmt.Println("write file error: ", err)
  16. }
  17. }
  18. /*
  19. 因为 writer 是带缓存,因此在调用 WriteString 方法时,其实内容是先写入缓存的,
  20. 所以需要调用 flush() 方法将缓存的内容真正写入到文件中,否则文件中会没有数据
  21. */
  22. err = writer.Flush()
  23. if err != nil {
  24. fmt.Println("flush error: ", err)
  25. }

}

  1. 3. 打开一个存在的文件,在原来的内容追加内容 "ABC!ENGLISH"
  2. ```go
  3. package main
  4. import (
  5. "bufio"
  6. "fmt"
  7. "os"
  8. )
  9. func main() {
  10. //打开一个存在的文件,在原来的内容追加内容“ABC!ENGLISH”
  11. filePath := "/Users/mac/Desktop/Linux/print.txt"
  12. file, err := os.OpenFile(filePath, os.O_APPEND | os.O_WRONLY, 0755)
  13. if err != nil {
  14. fmt.Println("open file error: ", err)
  15. return
  16. }
  17. //及时关闭 file 句柄
  18. defer func() {
  19. err = file.Close()
  20. if err != nil {
  21. fmt.Println("close file error: ", err)
  22. }
  23. }()
  24. //准备写入追加内容“ABC!ENGLISH”
  25. str := "ABC!ENGLISH\r\n"
  26. //写入时,使用带缓存的 *Writer
  27. writer := bufio.NewWriter(file)
  28. for i:=0; i< 10; i++ {
  29. _, err = writer.WriteString(str)
  30. if err != nil {
  31. fmt.Println("write file error: ", err)
  32. }
  33. }
  34. /*
  35. 因为 writer 是带缓存,因此在调用 WriteString 方法时,其实内容是先写入缓存的,
  36. 所以需要调用 flush() 方法将缓存的内容真正写入到文件中,否则文件中会没有数据
  37. */
  38. err = writer.Flush()
  39. if err != nil {
  40. fmt.Println("flush error: ", err)
  41. }
  42. }
  1. 打开一个存在的文件,将原来的内容读出显示在终端,并且追加 5 句 “hello,北京!” ```go package main

import ( “bufio” “fmt” “io” “os” )

func main() {

  1. //打开一个存在的文件,将原来的内容读出显示在终端,并且追加 5 句 "hello,北京!"
  2. filePath := "/Users/mac/Desktop/Linux/print.txt"
  3. file, err := os.OpenFile(filePath, os.O_RDWR | os.O_APPEND, 0755)
  4. if err != nil {
  5. fmt.Println("open file error: ", err)
  6. return
  7. }
  8. //及时关闭 file 句柄
  9. defer func() {
  10. err = file.Close()
  11. if err != nil {
  12. fmt.Println("close file error: ", err)
  13. }
  14. }()
  15. //先读取原来文件的内容,并显示在终端。
  16. reader := bufio.NewReader(file)
  17. for {
  18. str, err := reader.ReadString('\n')
  19. if err == io.EOF {
  20. //io.EOF 表示文件末尾
  21. break
  22. }
  23. //输出内容
  24. fmt.Print(str)
  25. }
  26. //准备写入追加5句"hello,北京!"
  27. str := "hello,北京!\r\n"
  28. //写入时,使用带缓存的 *Writer
  29. writer := bufio.NewWriter(file)
  30. for i:=0; i< 5; i++ {
  31. _, err = writer.WriteString(str)
  32. if err != nil {
  33. fmt.Println("write file error: ", err)
  34. }
  35. }
  36. /*
  37. 因为 writer 是带缓存,因此在调用 WriteString 方法时,其实内容是先写入缓存的,
  38. 所以需要调用 flush() 方法将缓存的内容真正写入到文件中,否则文件中会没有数据
  39. */
  40. err = writer.Flush()
  41. if err != nil {
  42. fmt.Println("flush error: ", err)
  43. }

}

  1. <a name="1e90a363"></a>
  2. ### 基本应用实例-方式二
  3. 1. 编写一个程序,将一个文件的内容,写入到另一个文件。注:这两个文件已经存在了。
  4. 1. 说明:使用 ioutil.ReadFile / ioutil.Writer 完成写文件的任务。
  5. ```go
  6. package main
  7. import (
  8. "fmt"
  9. "io/ioutil"
  10. )
  11. func main() {
  12. //将 /Users/mac/Desktop/Linux/phonelist.txt 文件内容导入到 /Users/mac/Desktop/Linux/print.txt
  13. //1. 首先将 /Users/mac/Desktop/Linux/phonelist.txt 读取到内存
  14. //2. 将读取到的内容写入 /Users/mac/Desktop/Linux/print.txt
  15. file1Path := "/Users/mac/Desktop/Linux/phonelist.txt"
  16. file2Path := "/Users/mac/Desktop/Linux/print.txt"
  17. content, err := ioutil.ReadFile(file1Path)
  18. if err != nil {
  19. //说明读取文件有错误
  20. fmt.Println("read file error:", err)
  21. return
  22. }
  23. err = ioutil.WriteFile(file2Path, content, 0755)
  24. if err != nil {
  25. fmt.Println("write file error:", err)
  26. }
  27. }

判断文件是否存在

  1. Golang 判断文件或文件夹是否存在的方法为使用 os.Stat() 函数返回的错误值进行判断:
    • 如果返回的错误为 nil,说明文件或文件夹存在
    • 如果返回的错误类型使用 os.IsNotExist() 判断为 true,说明文件或文件夹不存在
    • 如果返回的错误为其他类型,则不确定是否存在。
  2. 代码

    1. func PathExists(path string) (bool error) {
    2. _, err := os.Stat(path)
    3. if err == nil {
    4. //文件或者目录存在
    5. return true,nil
    6. }
    7. if os.IsNotExist(err) {
    8. return false,nil
    9. }
    10. return false,err
    11. }

    文件编程应用实例

    拷贝文件

  3. 说明:将一张图片/电影/mp3拷贝到另一个文件下。 ```go package main

import ( “bufio” “fmt” “io” “os” )

//自己编写函数,接收两个文件路径 srcFileName dstFileName func CopyFile(dstFileName string, srcFileName string) (written int64, err error) { srcfile, err := os.Open(srcFileName) if err != nil { fmt.Println(“open file error: “, err) return }

  1. //构建 srcfile ,获取到 Reader
  2. reader := bufio.NewReader(srcfile)
  3. //打开 dstFileName
  4. dstfile, err := os.OpenFile(dstFileName, os.O_WRONLY | os.O_CREATE, 0644)
  5. if err != nil {
  6. fmt.Println("open file error: ", err)
  7. return
  8. }
  9. //构建 dstfile ,获取到 Writer
  10. writer := bufio.NewWriter(dstfile)
  11. defer func() {
  12. err = srcfile.Close()
  13. if err != nil {
  14. fmt.Println("close file error: ", err)
  15. }
  16. }()
  17. defer func() {
  18. err = dstfile.Close()
  19. if err != nil {
  20. fmt.Println("close file error: ", err)
  21. }
  22. }()
  23. return io.Copy(writer, reader)

}

func main() {

  1. //将 /Users/mac/Desktop/PersonalWork/01.jpg 文件拷贝到 /Users/mac/Desktop/Linux/02.jpg
  2. //调用 CopyFile 完成文件拷贝
  3. srcFile := "/Users/mac/Desktop/PersonalWork/01.jpg"
  4. dstFile := "/Users/mac/Desktop/Linux/02.jpg"
  5. _, err := CopyFile(dstFile, srcFile)
  6. if err == nil {
  7. fmt.Println("拷贝完成")
  8. } else {
  9. fmt.Println("拷贝错误:", err)
  10. }

}

  1. <a name="d4cff46b"></a>
  2. ### 统计一个文件中含有的英文、数字、空格及其他字符数量。
  3. 1. 说明:统计一个文件中含有英文、数字、空格及其它字符数量。
  4. ```go
  5. package main
  6. import (
  7. "bufio"
  8. "fmt"
  9. "io"
  10. "os"
  11. )
  12. //定义一个结构体,用于保存统计结果
  13. type CharCount struct {
  14. ChCount int // 记录英文个数
  15. NumCount int // 记录数字个数
  16. SpaceCount int //记录空格的个数
  17. OtherCount int //记录其他字符的个数
  18. }
  19. func main() {
  20. //思路:打开一个文件,创建一个 Reader
  21. //每读取一行,就去统计该行有多少个 英文、数字、空格和其他字符
  22. //然后将结果保存到一个结构体中
  23. fileName := "/Users/mac/Desktop/Linux/distros.txt"
  24. file, err := os.Open(fileName)
  25. if err != nil {
  26. fmt.Print("open file error: ", err)
  27. return
  28. }
  29. defer func() {
  30. err = file.Close()
  31. if err != nil {
  32. fmt.Println("close file error: ", err)
  33. }
  34. }()
  35. //定义一个 CharCount 实例
  36. var count CharCount
  37. //创建一个 Reader
  38. reader := bufio.NewReader(file)
  39. //开始循环的读取 fileName 的内容
  40. for {
  41. str, err := reader.ReadString('\n')
  42. if err == io.EOF { //读到文件末尾就退出
  43. break
  44. }
  45. //遍历 str ,进行统计
  46. for _, value := range str {
  47. switch {
  48. case value >= 'a' && value <= 'z':
  49. fallthrough //穿透
  50. case value >= 'A' && value <= 'Z':
  51. count.ChCount++
  52. case value == ' ' || value == '\t':
  53. count.SpaceCount++
  54. case value >= '0' && value <= '9':
  55. count.NumCount++
  56. default:
  57. count.OtherCount++
  58. }
  59. }
  60. }
  61. //输出统计的结果看看是否正确
  62. fmt.Printf("字符的个数为%v 数字的个数为%v 空格的个数为%v 其他字符的个数为%v", count.ChCount, count.NumCount, count.SpaceCount, count.OtherCount)
  63. }

命令行参数

命令行参数一

需求

  1. 我们希望能获取到命令行输入的各种参数,该如何处理?

    基本介绍

  2. os.Args 是一个 string 的切片,用来存储所有的命令行参数。

    案例说明

  3. 案例一 ```go package main

import ( “fmt” “os” )

func main() {

  1. fmt.Println("命令行参数有: ", len(os.Args))
  2. // 遍历 os.Args 切片,就可以得到所有命令行输入参数值
  3. for index, value := range os.Args {
  4. fmt.Printf("args[%v] = %v \n", index, value)
  5. }

}

  1. <a name="2fdf61ce"></a>
  2. ### 命令行参数二
  3. <a name="6e274dcf"></a>
  4. #### flag 包用来解析命令行参数
  5. 1. 说明:前面的方式是比较原生的方式,对解析参数不是特别的方便,特别是带有指定参数形式的命令行。
  6. 1. 比如:`cmd > main.exe -f c:/aaa.txt -p 200 -u root` 这样的形式命令行,go 设计者给我们提供了 flag 包,可以方便的解析命令行参数,而且参数顺序可以随意。
  7. <a name="f05aba5b-1"></a>
  8. #### 案例说明
  9. 1. 案例一
  10. ```go
  11. package main
  12. import (
  13. "flag"
  14. "fmt"
  15. )
  16. func main() {
  17. //定义几个变量,用于接收命令行的参数
  18. var user string
  19. var pwd string
  20. var host string
  21. var port int
  22. // &user 就是接受用户命令行中输入的 -u 后面的参数值
  23. // "u", 就是 -u 指定参数
  24. // "", 默认值
  25. //"用户名,默认名为空",就是参数说明
  26. flag.StringVar(&user, "u", "", "用户名,默认为空")
  27. flag.StringVar(&pwd, "pwd", "", "密码,默认为空")
  28. flag.StringVar(&host, "h", "localhost", "主机名,默认为 localhost")
  29. flag.IntVar(&port, "port", 3306, "端口号,默认为 3306")
  30. //这里有一个非常重要的操作:转换,必须调用该方法
  31. flag.Parse()
  32. //输出结果
  33. fmt.Printf("user = %v pwd = %v host = %v port = %v",
  34. user, pwd, host, port)
  35. }

json

json 的基本介绍

  1. json(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。
  2. json 是在2001年开始推广使用的数据格式,目前已经成为主流的数据格式。
  3. json 易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络插损胡时会先将数据(结构体、map等)序列化成 json 字符串,到接受方得到 json 字符串时,在反序列话恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准。

    json 数据格式说明

  4. 在 js 语言中,一切都是对象。因此,任何支持的类型都可以通过 json 来表示,例如:字符串、数字、对象、数组等。

  5. json 键值对是用来保存数据一种方式,键/值对组合中的键名写在前面并用双引号””包裹,使用冒号:分隔,然后紧接着值。

    json 数据在线解析

  6. http://www.json.cn/ 网站可以验证一个 json 格式的数据是否正确。尤其是在我们编写复杂的 json 格式数据是,很有用。

    json 的序列化

    介绍

  7. json 序列化是指,将有 key-value 结构的数据类型(比如结构体、map、切片)序列化成 json 字符串的操作。

    应用案例

  8. struct 序列化 ```go package main

import ( “encoding/json” “fmt” )

//定义一个结构体 type Monster struct { Name string Age int Birthday string Salary float64 Skill string }

func testStruct() { //演示 monster := Monster{ Name: “牛魔王”, Age: 500, Birthday: “2011-11-11”, Salary: 8000.0, Skill: “牛魔拳”, }

  1. //将 monster 序列化
  2. data, err := json.Marshal(&monster)
  3. if err !=nil {
  4. fmt.Println("序列化错误 error: ", err)
  5. } else {
  6. //输出序列化后的结果
  7. fmt.Printf("monster序列化后 = %v \n", string(data))
  8. }

}

func main() { //演示将结构体、map、切片进行序列化 testStruct()

}

  1. 2. map 序列化
  2. ```go
  3. package main
  4. import (
  5. "encoding/json"
  6. "fmt"
  7. )
  8. //将 map 进行序列化
  9. func testMap() {
  10. //定义一个 map
  11. var a map[string]interface{}
  12. //使用 map,需要 make
  13. a = make(map[string]interface{})
  14. a["name"] = "红孩儿"
  15. a["age"] = 30
  16. a["address"] = "火云洞"
  17. //将 a 这个 map 进行序列化
  18. //将 monster 序列化
  19. data, err := json.Marshal(a)
  20. if err != nil {
  21. fmt.Println("a 序列化错误 error: ", err)
  22. } else {
  23. //输出序列化后的结果
  24. fmt.Printf("a 序列化后 = %v \n", string(data))
  25. }
  26. }
  27. func main() {
  28. //调用 testMap
  29. testMap()
  30. }
  1. slice 序列化 ```go package main

import ( “encoding/json” “fmt” )

//演示对切片进行序列化,我们切片 []map[string]interface{} func testSlice() { //定义一个切片 var slice []map[string]interface{} var m1 map[string]interface{}

  1. //使用 map 前,需要先 make
  2. m1 = make(map[string]interface{})
  3. m1["name"] = "Jack"
  4. m1["age"] = "7"
  5. m1["address"] = "北京"
  6. slice = append(slice, m1)
  7. var m2 map[string]interface{}
  8. //使用 map 前,需要先 make
  9. m2 = make(map[string]interface{})
  10. m2["name"] = "Tom"
  11. m2["age"] = "20"
  12. m2["address"] = "墨西哥"
  13. slice = append(slice, m2)
  14. //将切片进行序列化操作
  15. data, err := json.Marshal(slice)
  16. if err != nil {
  17. fmt.Println("slice 序列化错误 error: ", err)
  18. } else {
  19. //输出序列化后的结果
  20. fmt.Printf("slice 序列化后 = %v \n", string(data))
  21. }

}

func main() { //调用 testSlice,演示对切片的序列化 testSlice()

}

  1. 4. 基本数据类型序列化
  2. ```go
  3. package main
  4. import (
  5. "encoding/json"
  6. "fmt"
  7. )
  8. //对基本数据类型序列化,意义不大
  9. func testFloat64() {
  10. var num1 float64 = 2345.67
  11. //对 num1 进行序列化
  12. data, err := json.Marshal(num1)
  13. if err != nil {
  14. fmt.Println("num1 序列化错误 error: ", err)
  15. } else {
  16. fmt.Printf("num1 序列化后 = %v \n", string(data))
  17. }
  18. }
  19. func main() {
  20. //演示对基本数据类型的序列化
  21. testFloat64()
  22. }
  1. 注意事项:对于结构体的序列化,如果我们希望序列化后的 key 的名字,我们自己重新指定,那么可以给 struct 指定一个 tag 标签即可。 ```go package main

import ( “encoding/json” “fmt” )

//定义一个结构体 type Monster struct { Name string json:"name" //反射机制 Age int json:"age" Birthday string json:"birthday" Salary float64 json:"salary" Skill string json:"skill" }

func testStruct() { //演示 monster := Monster{ Name: “牛魔王”, Age: 500, Birthday: “2011-11-11”, Salary: 8000.0, Skill: “牛魔拳”, }

  1. //将 monster 序列化
  2. data, err := json.Marshal(&monster)
  3. if err !=nil {
  4. fmt.Println("monster 序列化错误 error: ", err)
  5. } else {
  6. //输出序列化后的结果
  7. fmt.Printf("monster 序列化后 = %v \n", string(data))
  8. }

}

func main() { //演示将结构体、map、切片进行序列化 testStruct()

}

  1. <a name="1bca3f17"></a>
  2. ### json 的反序列化
  3. <a name="f72dd4a6-2"></a>
  4. #### 基本介绍
  5. 1. json 反序列化是指,将json字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作。
  6. <a name="e54fecf2-1"></a>
  7. #### 应用案例
  8. 1. json 字符串反序列化成 struct
  9. ```go
  10. package main
  11. import (
  12. "encoding/json"
  13. "fmt"
  14. )
  15. //定义结构体
  16. type Monster struct {
  17. Name string
  18. Age int
  19. Birthday string
  20. Salary float64
  21. Skill string
  22. }
  23. //演示将 json 字符串,反序列化成 struct
  24. func unmarshalStruct() {
  25. // 说明 str 在项目开发中,是通过网络传输获取到... 获取是读取文件获取到
  26. str := "{\"Name\":\"牛魔王\",\"Age\":500,\"Birthday\":\"2011-11-11\",\"Salary\":8000,\"Skill\":\"牛魔拳\"}"
  27. //定义一个 Monster 的实例
  28. var monster Monster
  29. err := json.Unmarshal([]byte(str), &monster)
  30. if err != nil {
  31. fmt.Println("str 反序列化错误 error: ", err)
  32. } else {
  33. fmt.Printf("str 反序列化后 = %v", monster)
  34. }
  35. }
  36. func main() {
  37. // 调用 unmarshalStruct
  38. unmarshalStruct()
  39. }
  1. json 字符串反序列化成 map ```go package main

import ( “encoding/json” “fmt” )

//演示将 json 字符串,反序列化成 map func unmarshalMap() { // 说明 str 在项目开发中,是通过网络传输获取到… 获取是读取文件获取到 str := “{\”address\”:\”火云洞\”,\”age\”:30,\”name\”:\”红孩儿\”}”

  1. // 定义一个 map 的实例
  2. var a map[string]interface{}
  3. // a = make(map[string]interface{}) 反序列化不需要 make,因为 make 操作被封装到 Unmarshal 中
  4. err := json.Unmarshal([]byte(str), &a)
  5. if err != nil {
  6. fmt.Println("a 反序列化错误 error: ", err)
  7. } else {
  8. fmt.Printf("a 反序列化后 = %v", a)
  9. }

}

func main() { //调用函数 unmarshalMap unmarshalMap() }

  1. 3. json 字符串反序列化成 slice
  2. ```go
  3. package main
  4. import (
  5. "encoding/json"
  6. "fmt"
  7. )
  8. //演示将 json 字符串,反序列化成 slice
  9. func unmarshalSlice() {
  10. // 说明 str 在项目开发中,是通过网络传输获取到... 获取是读取文件获取到
  11. str := "[{\"address\":\"北京\",\"age\":\"7\",\"name\":\"Jack\"},{\"address\":\"墨西哥\",\"age\":\"20\",\"name\":\"Tom\"}]"
  12. //定义一个 slice
  13. var slice []map[string]interface{}
  14. err := json.Unmarshal([]byte(str), &slice)
  15. if err != nil {
  16. fmt.Println("slice 反序列化错误 error: ", err)
  17. } else {
  18. fmt.Printf("slice 反序列化后 = %v", slice)
  19. }
  20. }
  21. func main() {
  22. //调用函数 unmarshalSlice()
  23. unmarshalSlice()
  24. }
  1. 对上面代码的小结说明
    • 在反序列化一个 json 字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
    • 如果 json 字符串是通过程序获取到的,则不需要再对双引号进行转义处理。

课程来源