综合练习,写一个Student结构体,并绑定两个带参数的方法Store()ReStore(),并利用到go语言中的,encoding/json, io包、bufio包以及os包。从而完成将结构体实例内容序列化,写入到文件中,然后再从文件中取出,并反序列化,还原成结构体的内容。
model/student.go
package model
import (
"bufio"
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
//`json:`为Tag 标签,可以输出首字母为小写的字符串或者任何定义的字符串
type Student struct {
StuNum int `json:"stuNum"`
Age int `json:"age"`
Name string `json:"name"`
Skill string `json:"skill"`
Score float64 `json:"score"`
}
//定义一个结构体数组
type Students []Student
type Operate interface {
Store(filename string) bool
ReStore(filename string) (*Students,bool)
}
//序列化的函数方法
func Serialize(this interface{}) []byte {
dataBytes,err := json.Marshal(this)
if err != nil {
fmt.Printf("marshal error =%v\n",err)
return nil
}
return dataBytes
}
//定义一个[]Students结构体的Store()的方法
//并采用os.OpenFile()和bufio包的NewWriter()的方法来打开文件,如果没有此文件则创建
//并将打开的文件清空后,写入新的内容
func (ss *Students) Store(filepath string) bool {
contentBytes := Serialize(&ss)
file,err := os.OpenFile(filepath,os.O_RDWR | os.O_CREATE | os.O_TRUNC,0777)
if err != nil {
fmt.Printf("open file error = %v\n",err)
return false
}
defer file.Close()
//构造一个writer函数,
writer := bufio.NewWriter(file)
for i := 0; i < len(string(contentBytes)); i++ {
//调用WriteByte()按字节写入
writer.WriteByte(contentBytes[i])
}
//从缓冲中取出
writer.Flush()
fmt.Println(string(contentBytes))
return true
}
//定义一个[]Strudents结构体的ReStore()的方法
//采用os.Open()和ioutil.ReadAll(),来读取较大的文件
func (ss *Students) ReStore(filename string) (*Students,bool) {
file, err := os.Open(filename)
if err != nil {
fmt.Printf("Open file error =%v\n",err)
}
defer file.Close()
contentBytes,err := ioutil.ReadAll(file)
if err != nil {
fmt.Println("Read file error =",err)
}
err = json.Unmarshal(contentBytes,&ss)
if err != nil {
fmt.Println("Unmarshal data error = ",err)
}
return ss,true
}
//读取文件的另一种函数方法
//采用os.Open()和file.Read()的方法,即以文件对象调用Read()的方法
func ReadFile(filename string) {
fileObj,err := os.Open(filename)
if err == nil {
defer fileObj.Close()
//定义一个新的byte切片列表,空间设置1024,根据要读入的文件大小自定义。如果太小了,会造成文件读取不完整。
buf := make([]byte, 1024)
n,err := fileObj.Read(buf)
if err == nil {
fmt.Println("The number of bytes read:",n,"Buf length:",len(buf))
fmt.Println("Use os.Open and File's Read method to read a file:",string(buf))
}
}
}
main/main.go
package main
import (
"fmt"
"go_code/.../model"
)
func main() {
filepath := "./student.txt"
var stus = &model.Students{model.Student{
StuNum: 1,
Name : "许小明",
Age : 17,
Skill : "游泳",
Score: 613.5,
},
model.Student{
StuNum: 2,
Name : "王怡人",
Age : 16,
Skill : "乒乓",
Score: 583.5,
},
model.Student{
StuNum: 3,
Name : "李安然",
Age : 17,
Skill : "篮球",
Score: 683.5,
},
}
//重新定义个operate,并将stus赋值给operate
var operate model.Operate = stus
ok := operate.Store(filepath)
if ok {
fmt.Println("this data stroed successfully...")
}
stus,flag := operate.ReStore(filepath)
if flag {
fmt.Printf("this data retrieved from this path: %q, contents is : %v\n",filepath,*stus)
}else {
fmt.Println("this data retrieved failed...")
}
model.ReadFile(filepath)
}
输出的结果:
[{"stuNum":1,"age":17,"name":"许小明","skill":"游泳","score":613.5},{"stuNum":2,"age":16,"name":"王怡人","skill":"乒乓","score":583.5},{"stuNum":3,"age":17,"name":"李安然","skill":"篮球","score":683.5}]
this data stroed successfully...
this data retrieved from this path: "./student.txt", contents is : [{1 17 许小明 游泳 613.5} {2 16 王怡人 乒乓 583.5} {3 17 李安然 篮球 683.5}]
The number of bytes read: 217 Buf length: 1024
Use os.Open and File's Read method to read a file: [{"stuNum":1,"age":17,"name":"许小明","skill":"游泳","score":613.5},{"stuNum":2,"age":16,"name":"王怡人","skill":"乒乓","score":583.5},{"stuNum":3,"age":17,"name":"李安然","skill":"篮球","score":683.5}]