一、简介
文件操作对于我们来说也是非常常用的,在python中使用open函数来对文件进行操作,而在go语言中我们使用os.File对文件进行操作。
二、终端读写
操作终端句柄常量
os.Stdin: 标准输入
os.Stdout: 标准输出
读写示例:
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"<span style="color: #000000;">
)
<span style="color: #0000ff;">var<span style="color: #000000;">(
username,password <span style="color: #0000ff;">string<span style="color: #000000;">
)
func main() {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">请输入用户名:<span style="color: #800000;">"<span style="color: #000000;">)
fmt.Scanf(<span style="color: #800000;">"<span style="color: #800000;">%s<span style="color: #800000;">",&username) <span style="color: #008000;">//<span style="color: #008000;"> 键盘输入
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">请输入密码:<span style="color: #800000;">"<span style="color: #000000;">)
fmt.Scanf(<span style="color: #800000;">"<span style="color: #800000;">%s<span style="color: #800000;">",&<span style="color: #000000;">password)
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">username:%s password:%s\n<span style="color: #800000;">"<span style="color: #000000;">,username,password)
<span style="color: #0000ff;">var msg [<span style="color: #800080;">5]<span style="color: #0000ff;">byte<span style="color: #000000;">
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">请输入名称:<span style="color: #800000;">"<span style="color: #000000;">)
n,err :=<span style="color: #000000;"> os.Stdin.Read(msg[:])
<span style="color: #0000ff;">if err ==<span style="color: #000000;"> nil {
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">len: %d,msg : %s<span style="color: #800000;">"<span style="color: #000000;">,n,msg[:])
<span style="color: #0000ff;">return<span style="color: #000000;">
}
}
<span style="color: #008000;">//<span style="color: #008000;">请输入用户名:
<span style="color: #008000;">//<span style="color: #008000;">wd
<span style="color: #008000;">//<span style="color: #008000;">请输入密码:
<span style="color: #008000;">//<span style="color: #008000;">123
<span style="color: #008000;">//<span style="color: #008000;">username:wd password:123
<span style="color: #008000;">//<span style="color: #008000;">请输入名称:
<span style="color: #008000;">//<span style="color: #008000;">ad
<span style="color: #008000;">//<span style="color: #008000;">len: 3,msg : ad
三、文件操作
读写参数@H_403_171@
文件打开模式:
文件权限:
-
r :可读,对应的004
-
w:可写,对应002
-
x:可执行,对应001
文件读取@H_403_171@
Read
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">io<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
file,err := os.Open(<span style="color: #800000;">"<span style="color: #800000;">/home/test.txt<span style="color: #800000;">") <span style="color: #008000;">//只读打开
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">open file error: <span style="color: #800000;">"<span style="color: #000000;">,err)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
defer file.Close() <span style="color: #008000;">//<span style="color: #008000;">关闭文件
context := make([]<span style="color: #0000ff;">byte,<span style="color: #800080;">100<span style="color: #000000;">)
<span style="color: #0000ff;">for<span style="color: #000000;"> {
readNum,err :=<span style="color: #000000;"> file.Read(context)
<span style="color: #0000ff;">if err != nil && err !=<span style="color: #000000;"> io.EOF {
<span style="color: #008000;">//<span style="color: #008000;">panic(err) <span style="color: #008000;">//<span style="color: #008000;">有错误抛出异常
<span style="color: #000000;"> }
<span style="color: #0000ff;">if <span style="color: #800080;">0 ==<span style="color: #000000;"> readNum {
<span style="color: #0000ff;">break <span style="color: #008000;">//<span style="color: #008000;">当读取完毕时候退出循环
<span style="color: #000000;"> }
}
<span style="color: #0000ff;">for k,v :=<span style="color: #000000;"> range context{
println(k,v)
}
}
Seek
按行读取ReadLine
<span style="color: #800000;">"<span style="color: #800000;">bufio<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">io<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
file,err := os.Open(<span style="color: #800000;">"<span style="color: #800000;">/home/test.txt<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(err)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
defer file.Close()
reader :=<span style="color: #000000;"> bufio.NewReader(file)
<span style="color: #0000ff;">var line []<span style="color: #0000ff;">byte
<span style="color: #0000ff;">for<span style="color: #000000;"> {
data,prefix,err :=<span style="color: #000000;"> reader.ReadLine()
<span style="color: #0000ff;">if err ==<span style="color: #000000;"> io.EOF {
<span style="color: #0000ff;">break<span style="color: #000000;">
}
line </span>=<span style="color: #000000;"> append(line,data...)
</span><span style="color: #0000ff;">if</span> !<span style="color: #000000;">prefix {
fmt.Printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">data:%s\n</span><span style="color: #800000;">"</span>,<span style="color: #0000ff;">string</span><span style="color: #000000;">(line))
line </span>=<span style="color: #000000;"> line[:]
}
}
}
读取整个文件ReadAll
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">io/IoUtil<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
fileName := <span style="color: #800000;">"<span style="color: #800000;">/home/test.txt<span style="color: #800000;">"<span style="color: #000000;">
file,err :</span>= os.OpenFile(fileName,os.O_CREATE|os.O_RDWR,<span style="color: #800080;">0666</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">if</span> err !=<span style="color: #000000;"> nil {
fmt.Println(</span><span style="color: #800000;">"</span><span style="color: #800000;">Open file error: </span><span style="color: #800000;">"</span><span style="color: #000000;">,err)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">
}
defer file.Close()
buf,err :</span>=<span style="color: #000000;"> <a href="/tag/IoU/" target="_blank" class="keywords">IoU</a>til.ReadAll(file)
</span><span style="color: #008000;">//</span><span style="color: #008000;">buf,err := <a href="/tag/IoU/" target="_blank" class="keywords">IoU</a>til.ReadFile(fileName)</span>
<span style="color: #0000ff;">if</span> err !=<span style="color: #000000;"> nil {
fmt.Fprintf(os.Stderr,</span><span style="color: #800000;">"</span><span style="color: #800000;">File Error: %s\n</span><span style="color: #800000;">"</span><span style="color: #000000;">,err)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">
}
fmt.Printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">%s\n</span><span style="color: #800000;">"</span>,<span style="color: #0000ff;">string</span><span style="color: #000000;">(buf))
}
四、带缓冲区的读写(bufio)
带缓冲的读写操作作用是为了减少磁盘io次数,通过包bufio实现,这里做简单示例说明,bufio包后续再介绍.
标准输入读示例:
<span style="color: #800000;">"<span style="color: #800000;">bufio<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
reader := bufio.NewReader(os.Stdin) <span style="color: #008000;">//<span style="color: #008000;"> 创建从标准输入中读取数据对象
str,err := reader.ReadString(<span style="color: #800000;">'<span style="color: #800000;">\n<span style="color: #800000;">') <span style="color: #008000;">//<span style="color: #008000;">读数据,bytes类型是单引号
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">read fail<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">input string: <span style="color: #800000;">"<span style="color: #000000;">,str)
}
<span style="color: #008000;">//<span style="color: #008000;">adad
<span style="color: #008000;">//<span style="color: #008000;">input string: adad
从文件读取示例
<span style="color: #800000;">"<span style="color: #800000;">bufio<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">io<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
file,err := os.Open(<span style="color: #800000;">"<span style="color: #800000;">test.txt<span style="color: #800000;">") <span style="color: #008000;">//<span style="color: #008000;">以只读方式打开文件
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">open file fail err:<span style="color: #800000;">"<span style="color: #000000;">,err)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
reader := bufio.NewReader(file) <span style="color: #008000;">//<span style="color: #008000;"> 创建读取数据对象
<span style="color: #000000;"> defer file.Close()
<span style="color: #0000ff;">for<span style="color: #000000;">{
str,err := reader.ReadString(<span style="color: #800000;">'<span style="color: #800000;">\n<span style="color: #800000;">') <span style="color: #008000;">//<span style="color: #008000;">读数据,bytes类型是单引号,回车结束。
<span style="color: #0000ff;">if err ==<span style="color: #000000;"> io.EOF {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">read over<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">break<span style="color: #000000;">
}
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil{
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">error :<span style="color: #800000;">"<span style="color: #000000;">,err)
<span style="color: #0000ff;">break<span style="color: #000000;">
}
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">STRING: <span style="color: #800000;">"<span style="color: #000000;">,str)
}
}
写文件示例:
<span style="color: #800000;">"<span style="color: #800000;">bufio<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
file,err := os.OpenFile(<span style="color: #800000;">"<span style="color: #800000;">test.txt<span style="color: #800000;">",os.O_WRONLY,<span style="color: #800080;">0644) <span style="color: #008000;">//<span style="color: #008000;">以写方式打开文件
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">open file fail err:<span style="color: #800000;">"<span style="color: #000000;">,err)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
writer := bufio.NewWriter(file) <span style="color: #008000;">//<span style="color: #008000;"> 创建写对象
<span style="color: #000000;"> defer file.Close()
<span style="color: #0000ff;">var str <span style="color: #0000ff;">string<span style="color: #000000;">
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">请输入内容:<span style="color: #800000;">"<span style="color: #000000;">)
fmt.Scanf(<span style="color: #800000;">"<span style="color: #800000;">%s<span style="color: #800000;">",&<span style="color: #000000;">str)
writer.WriteString(str)
writer.Flush() <span style="color: #008000;">//<span style="color: #008000;"> 将缓冲区内容写入文件,默认写入到文件开头
<span style="color: #000000;">
}
五、命令行参数
命令行参数:程序启动或者停止时候,在命令行中给定的参数就是命令行参数。例如start.sh -p 8080
go语言中提供了两种处理命令行参数的包os.Agrs和flag包。
优缺点:
- os.Agrs提供了简单的命令行参数,以命令行参数个数作为标识,参数列表是一个切片,索引0代表程序本身,1代表第一个参数,以此类推,没有更细粒度的参数区分,使用起来简单
- flag提供了更为科学的命令行参数处理办法,提供更细粒度的和更全的参数解析,推荐使用
os.Agrs@H_403_171@
os.Args 提供原始命令行参数访问功能。注意,切片中的第一个参数是该程序的路径,并且 os.Args[1:]保存所有程序的的参数。
示例:
<span style="color: #800000;">"<span style="color: #800000;">os<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
<span style="color: #0000ff;">if len(os.Args) < <span style="color: #800080;">2<span style="color: #000000;"> {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">no args<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
println(<span style="color: #800000;">"<span style="color: #800000;">script name: <span style="color: #800000;">",os.Args[<span style="color: #800080;">0<span style="color: #000000;">])
<span style="color: #0000ff;">for i :=<span style="color: #000000;"> range os.Args {
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">this is %d arg : %s\n<span style="color: #800000;">"<span style="color: #000000;">,i,os.Args[i])
}
}
<span style="color: #008000;">//<span style="color: #008000;"> 执行./eg1 name age body
<span style="color: #008000;">//<span style="color: #008000;">结果:
<span style="color: #008000;">//<span style="color: #008000;">script name: ./eg1
<span style="color: #008000;">//<span style="color: #008000;">this is 0 arg : ./eg1
<span style="color: #008000;">//<span style="color: #008000;">this is 1 arg : name
<span style="color: #008000;">//<span style="color: #008000;">this is 2 arg : age
<span style="color: #008000;">//<span style="color: #008000;">this is 3 arg : body
flag包@H_403_171@
Flag类型是一个结构体,其定义如下:
flag包提供了一系列解析命令行参数的功能接口,其定义的命令行参数方式有以下几种:
定义flag参数
方式一:通过flag.String(),Bool(),Int()
等flag.Xxx()
方法,该种方式返回一个相应的指针
示例:
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">flag<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
ip := flag.String(<span style="color: #800000;">"<span style="color: #800000;">ip<span style="color: #800000;">",<span style="color: #800000;">"<span style="color: #800000;">10.0.0.230<span style="color: #800000;">",<span style="color: #800000;">"<span style="color: #800000;">server listen ip<span style="color: #800000;">") <span style="color: #008000;">//<span style="color: #008000;">参数一为命令行接受的参数名称,参数二为默认值,参数三为描述信息
port := flag.Int(<span style="color: #800000;">"<span style="color: #800000;">port<span style="color: #800000;">",<span style="color: #800080;">80,<span style="color: #800000;">"<span style="color: #800000;">server port<span style="color: #800000;">"<span style="color: #000000;">)
flag.Parse()
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">ip<span style="color: #800000;">",<span style="color: #000000;">ip)
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">port<span style="color: #800000;">",<span style="color: #000000;">port)
}
<span style="color: #008000;">//<span style="color: #008000;">使用go build 编译 执行./eg1 --port 8080 -ip 10.0.0.241
<span style="color: #008000;">//<span style="color: #008000;">结果
<span style="color: #008000;">//<span style="color: #008000;">ip 10.0.0.241
<span style="color: #008000;">//<span style="color: #008000;">port 8080
方式二:
通过flag.XxxVar()
方法将flag绑定到一个变量,该种方式返回值类型,我们将上述示例改为flag.xxxVar()
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">flag<span style="color: #800000;">"<span style="color: #000000;">
)
func main() {
<span style="color: #0000ff;">var ip <span style="color: #0000ff;">string
<span style="color: #0000ff;">var port <span style="color: #0000ff;">int<span style="color: #000000;">
flag.StringVar(&ip,<span style="color: #800000;">"<span style="color: #800000;">ip<span style="color: #800000;">",<span style="color: #800000;">"<span style="color: #800000;">server listen ip<span style="color: #800000;">") <span style="color: #008000;">//<span style="color: #008000;">参数一是变量,后面与flag.String一样
flag.IntVar(&port,<span style="color: #800000;">"<span style="color: #800000;">port<span style="color: #800000;">",<span style="color: #800000;">"<span style="color: #800000;">server port<span style="color: #800000;">"<span style="color: #000000;">)
flag.Parse()
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">ip<span style="color: #800000;">"<span style="color: #000000;">,ip)
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">port<span style="color: #800000;">"<span style="color: #000000;">,port)
}
<span style="color: #008000;">//<span style="color: #008000;"> 同样编译完成运行./eg1 --port 8080 -ip 10.0.0.241
<span style="color: #008000;">//<span style="color: #008000;">结果
<span style="color: #008000;">//<span style="color: #008000;">ip 10.0.0.241
<span style="color: #008000;">//<span style="color: #008000;">port 8080
六、序列化、反序列化
应用程序交互,即数据的交互,数据交互永远离不开序列化,常见的数据库交互格式如json、xml,在go语言中提供了诸多的序列化格式:
json@H_403_171@
json格式数据是现在数据交互用的最多的数据格式,go一般通过json.Marshal()进行序列化,通过json.Marshal()反序列化。
示例一:序列化struct
<span style="color: #800000;">"<span style="color: #800000;">encoding/json<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string json:<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span>
<span style="color: #008000;">//<span style="color: #008000;">序列化时将字段变为小写
Age <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;">age</span><span style="color: #800000;">"</span><span style="color: #000000;">
score <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;"><a href="/tag/score/" target="_blank" class="keywords">score</a></span><span style="color: #800000;">"</span><span style="color: #000000;">
}
func main() {
stu1 :=&Student{Name:<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">",Age:<span style="color: #800080;">22,score:<span style="color: #800080;">100<span style="color: #000000;">}
res,err :=<span style="color: #000000;"> json.Marshal(stu1)
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">json encode error<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">json string: %s<span style="color: #800000;">"<span style="color: #000000;">,res)
}<span style="color: #008000;">//<span style="color: #008000;"> 结果
<span style="color: #008000;">//<span style="color: #008000;">json string :{"name":"wd","age":22,"score":100}
示例二:序列化map
<span style="color: #800000;">"<span style="color: #800000;">encoding/json<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
type Dictmap map[<span style="color: #0000ff;">int]<span style="color: #0000ff;">string<span style="color: #000000;">
func main() {
map1 :</span>= &Dictmap{<span style="color: #800080;">1</span>:<span style="color: #800000;">"</span><span style="color: #800000;">wd</span><span style="color: #800000;">"</span>,<span style="color: #800080;">2</span>:<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">}
res,err :</span>=<span style="color: #000000;"> json.Marshal(map1)
</span><span style="color: #0000ff;">if</span> err !=<span style="color: #000000;"> nil {
fmt.Println(</span><span style="color: #800000;">"</span><span style="color: #800000;">json encode error</span><span style="color: #800000;">"</span><span style="color: #000000;">)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">
}
fmt.Printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">json string: %s</span><span style="color: #800000;">"</span><span style="color: #000000;">,res)
}
<span style="color: #008000;">//<span style="color: #008000;"> 结果:json string: {"1":"wd","2":"name"}
反序列化
反序列化过程中需要注意,数据格式是byte切片
反序列化struct示例:
<span style="color: #800000;">"<span style="color: #800000;">encoding/json<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string json:<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">
Age <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;">age</span><span style="color: #800000;">"</span><span style="color: #000000;">
score <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;"><a href="/tag/score/" target="_blank" class="keywords">score</a></span><span style="color: #800000;">"</span><span style="color: #000000;">
}
func main() {
data := {<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span>:<span style="color: #800000;">"</span><span style="color: #800000;">wd</span><span style="color: #800000;">"</span>,<span style="color: #800000;">"</span><span style="color: #800000;">age</span><span style="color: #800000;">"</span>:<span style="color: #800080;">22</span>,<span style="color: #800000;">"</span><span style="color: #800000;"><a href="/tag/score/" target="_blank" class="keywords">score</a></span><span style="color: #800000;">"</span>:<span style="color: #800080;">100</span><span style="color: #000000;">}
<span style="color: #0000ff;">var<span style="color: #000000;"> stu1 Student
err := json.Unmarshal([]<span style="color: #0000ff;">byte(data),&<span style="color: #000000;">stu1)
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">json decode error: <span style="color: #800000;">"<span style="color: #000000;">,err)
<span style="color: #0000ff;">return<span style="color: #000000;">
}
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">struct obj is : %s<span style="color: #800000;">"<span style="color: #000000;">,stu1.Name)
}
<span style="color: #008000;">//<span style="color: #008000;">结果
<span style="color: #008000;">//<span style="color: #008000;">struct obj is : wd
gob@H_403_171@
Gob(Go binary 的缩写) 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式,其方法在encoding中,类似于 Python 的 "pickle" ,这样的数据格式只能在go程序之间进行数据交互。
序列化和反序列化示例:
<span style="color: #800000;">"<span style="color: #800000;">bytes<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">encoding/gob<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
type Student <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Name <span style="color: #0000ff;">string json:<span style="color: #800000;">"</span><span style="color: #800000;">name</span><span style="color: #800000;">"</span><span style="color: #000000;">
Age <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;">age</span><span style="color: #800000;">"</span><span style="color: #000000;">
score <span style="color: #0000ff;">int json:<span style="color: #800000;">"</span><span style="color: #800000;"><a href="/tag/score/" target="_blank" class="keywords">score</a></span><span style="color: #800000;">"</span><span style="color: #000000;">
}
func main() {
stu1 := Student{<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">",<span style="color: #800080;">22,<span style="color: #800080;">100<span style="color: #000000;">}
<span style="color: #0000ff;">var<span style="color: #000000;"> buf bytes.Buffer
enc :</span>= gob.NewEncoder(&<span style="color: #000000;">buf)
dec :</span>= gob.NewDecoder(&<span style="color: #000000;">buf)
</span><span style="color: #0000ff;">if</span> err := enc.Encode(stu1); err !=<span style="color: #000000;"> nil {
fmt.Println(</span><span style="color: #800000;">"</span><span style="color: #800000;">encode error:</span><span style="color: #800000;">"</span><span style="color: #000000;">,err)
}
fmt.Printf(</span><span style="color: #800000;">"</span><span style="color: #800000;">gob res %s: \n</span><span style="color: #800000;">"</span><span style="color: #000000;">,enc)
</span><span style="color: #0000ff;">var</span><span style="color: #000000;"> stu2 Student
</span><span style="color: #0000ff;">if</span> err := dec.Decode(&stu2); err !=<span style="color: #000000;"> nil {
fmt.Println(</span><span style="color: #800000;">"</span><span style="color: #800000;">decode error:</span><span style="color: #800000;">"</span><span style="color: #000000;">,err)
}
fmt.Println(</span><span style="color: #800000;">"</span><span style="color: #800000;">decode res:</span><span style="color: #800000;">"</span><span style="color: #000000;">,stu2)
} </span><span style="color: #008000;">//</span><span style="color: #008000;">decode res: wd</span></pre>
403_171@
endoding包中的binnary主要用于二进制数据序列化,但是局限性较高。
注意: 如果字段中有不确定大小的类型,如 int,slice,string 等,则会报错。使用binary.Write进行序列化时候,数据类型必须是固定大小如:int只能使用int64、int32,切片需要有固定长度。
<span style="color: #800000;">"<span style="color: #800000;">bytes<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">encoding/binary<span style="color: #800000;">"
<span style="color: #800000;">"<span style="color: #800000;">fmt<span style="color: #800000;">"<span style="color: #000000;">
)
type Message <span style="color: #0000ff;">struct<span style="color: #000000;"> {
Id uint64
Size uint64
}
func main() {
m1 := Message{<span style="color: #800080;">1,<span style="color: #800080;">22<span style="color: #000000;">}
buf := <span style="color: #0000ff;">new<span style="color: #000000;">(bytes.Buffer)
err := binary.Write(buf,binary.LittleEndian,m1) <span style="color: #008000;">//<span style="color: #008000;"> 序列化
<span style="color: #0000ff;">if err !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">binary write error:<span style="color: #800000;">"<span style="color: #000000;">,err)
}
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">binary res: %s \n <span style="color: #800000;">",m1) <span style="color: #008000;">//<span style="color: #008000;">binary res: {%!s(uint64=1) %!s(uint64=22)}
<span style="color: #0000ff;">var<span style="color: #000000;"> m2 Message
err1 := binary.Read(buf,&m2); <span style="color: #008000;">//<span style="color: #008000;">反序列化
<span style="color: #0000ff;">if err1 !=<span style="color: #000000;"> nil {
fmt.Println(<span style="color: #800000;">"<span style="color: #800000;">binary read error:<span style="color: #800000;">"<span style="color: #000000;">,err)
}
fmt.Printf(<span style="color: #800000;">"<span style="color: #800000;">decode res: %s<span style="color: #800000;">",m2) <span style="color: #008000;">//<span style="color: #008000;">decode res: {%!s(uint64=1) %!s(uint64=22)}
}
ProtoBuf@H_403_171@
对于ProtoBuf并不是go语言中包自带的,需要自行安装你需要安装protoc编译器,以及protoc库以及生成相关的类
安装方法(linux或者mac):
使用:
创建一个test.proto文件
<span style="color: #000000;">package test; <span style="color: #008000;">//<span style="color: #008000;">手机类型
<span style="color: #008000;">//<span style="color: #008000;">枚举类型第一个字段必须为0
<span style="color: #0000ff;">enum<span style="color: #000000;"> PhoneType {
HOME = <span style="color: #800080;">0<span style="color: #000000;">;
WORK = <span style="color: #800080;">1<span style="color: #000000;">;
}
<span style="color: #008000;">//<span style="color: #008000;">手机
<span style="color: #000000;">message Phone {
PhoneType type = <span style="color: #800080;">1<span style="color: #000000;">;
<span style="color: #0000ff;">string number = <span style="color: #800080;">2<span style="color: #000000;">;
}
<span style="color: #008000;">//<span style="color: #008000;">人
<span style="color: #000000;">message Person {
<span style="color: #008000;">//<span style="color: #008000;">后面的数字表示标识号
int32 id = <span style="color: #800080;">1<span style="color: #000000;">;
<span style="color: #0000ff;">string name = <span style="color: #800080;">2<span style="color: #000000;">;
<span style="color: #008000;">//<span style="color: #008000;">repeated表示可重复
<span style="color: #008000;">//<span style="color: #008000;">可以有多个手机
repeated Phone phones = <span style="color: #800080;">3<span style="color: #000000;">;
}
<span style="color: #008000;">//<span style="color: #008000;">联系簿
<span style="color: #000000;">message ContactBook {
repeated Person persons = <span style="color: #800080;">1<span style="color: #000000;">;
}
运行命令:protoc --go_out=. *.proto,生成test.pb.go文件
使用protobuf