本文接上一篇:。
关于csv文件的说明,见
当数据存储到了内存中,可以在需要的时候持久化保存到磁盘文件中。比如保存为csv格式的文件,下一篇再介绍序列化持久到文件中。
下面是持久化到csv文件的函数代码:
func storetocsv(filename string, posts map[int]*post) { // 创建文件 csvfile, err := os.create(filename) if err != nil { panic(err) } defer csvfile.close() // 获取csv的writer writer := csv.newwriter(csvfile) // 将map中的post转换成slice,因为csv的write需要slice参数 // 并写入csv文件 for _, post := range posts { record := []string{strconv.itoa(post.id), post.content, post.author} err1 := writer.write(record) if err1 != nil { panic(err1) } } // 确保所有内存数据刷到csv文件 writer.flush() }
这个函数的逻辑很简单,无需过多的解释。需要注意的是,os.create()
函数在文件存在时会截断文件,如有需要,可以考虑使用追加写入的相关函数。
当需要将保存在内存中的post保存到csv文件时,只需调用该函数,传递一个文件名以及postbyid作为参数即可:
storetocsv("d:/a.csv", postbyid)
保存之后,以下是a.csv文件的内容:
2,hello 2,userb 3,hello 3,userc 4,hello 4,usera 1,hello 1,usera
数据保存到了csv文件,自然需要从csv文件中读取数据到内存。以下是读取csv文件的函数:
func load(filename string) []*post { // 打开文件 file, err := os.open(filename) if err != nil { panic(err) } defer file.close() // 获取csv的reader reader := csv.newreader(file) // 设置fieldsperrecord为-1 reader.fieldsperrecord = -1 // 读取文件中所有行保存到slice中 records, err := reader.readall() if err != nil { panic(err) } var posts []*post // 将每一行数据保存到内存slice中 for _, item := range records { id, _ := strconv.atoi(item[0]) post := &post{id: id, content: item[1], author: item[2]} posts = append(posts, post) } return posts }
逻辑也很简单,唯一需要注意的是filedsperrecord=-1
:
这个load()函数返回一个slice,这个slice中保存了所有读取到的文章指针。
s := load("d:/a.csv")
因为使用var postbyid map[int]*post
和var postsbyauthor map[string][]*post
保存一篇篇的文章,迭代此slice即可将slice中的post保存到这两个map中。
for _, post := range s { store(post) }
然后就可以从这两个map中按照id或者按照author进行检索:
fmt.println(postbyid[1]) fmt.println(postbyid[2]) for _, post := range postsbyauthor["usera"] { fmt.println(post) }
下面是完整的保存到csv文件以及读取csv文件的代码:
package main import ( "encoding/csv" "fmt" "os" "strconv" ) type post struct { id int content string author string } var postbyid map[int]*post var postsbyauthor map[string][]*post func store(post *post) { postbyid[post.id] = post postsbyauthor[post.author] = append(postsbyauthor[post.author], post) } func storetocsv(filename string, posts map[int]*post) { csvfile, err := os.create(filename) if err != nil { panic(err) } defer csvfile.close() writer := csv.newwriter(csvfile) for _, post := range posts { record := []string{strconv.itoa(post.id), post.content, post.author} err1 := writer.write(record) if err1 != nil { panic(err1) } } writer.flush() } func load(filename string) []*post { file, err := os.open(filename) if err != nil { panic(err) } defer file.close() reader := csv.newreader(file) reader.fieldsperrecord = -1 records, err := reader.readall() if err != nil { panic(err) } var posts []*post for _, item := range records { id, _ := strconv.atoi(item[0]) post := &post{id: id, content: item[1], author: item[2]} posts = append(posts, post) } return posts } func main() { postbyid = make(map[int]*post) postsbyauthor = make(map[string][]*post) // 模拟几篇文章 post1 := &post{id: 1, content: "hello 1", author: "usera"} post2 := &post{id: 2, content: "hello 2", author: "userb"} post3 := &post{id: 3, content: "hello 3", author: "userc"} post4 := &post{id: 4, content: "hello 4", author: "usera"} // 存储到内存中 store(post1) store(post2) store(post3) store(post4) // 将内存中的map容器,保存到csv文件中 storetocsv("d:/a.csv", postbyid) // 为了测试,此处将已保存在内存中的数据清空 postbyid = map[int]*post{} postsbyauthor = map[string][]*post{} // 下面是加载csv文件 s := load("d:/a.csv") for _, post := range s { store(post) } // 检索 fmt.println(postbyid[1]) fmt.println(postbyid[2]) for _, post := range postsbyauthor["usera"] { fmt.println(post) } for _, post := range postsbyauthor["userc"] { fmt.println(post) } }
运行结果:
&{1 hello 1 usera} &{2 hello 2 userb} &{1 hello 1 usera} &{4 hello 4 usera} &{3 hello 3 userc}
如对本文有疑问, 点击进行留言回复!!
网友评论