Go Web:数据存储(2)——CSV文件
程序员文章站
2022-06-05 16:12:53
存储到CSV文件中 "1.内存存储" "2.CSV文件存储" "3.gob序列化存储" 本文接上一篇: "内存存储" 。 关于CSV文件的说明,见 "csv文件格式" 当数据存储到了内存中,可以在需要的时候持久化保存到磁盘文件中。比如保存为csv格式的文件,下一篇再介绍序列化持久到文件中。 下面是持 ......
存储到csv文件中
本文接上一篇:。
关于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
:
- 设置为负数表示读取时每条记录的字段数量可以随意
- 如果设置为正数n,则表示每条记录必须且只读取n个字段,如果字段少于n,则报错
- 如果设置为0,则表示按照第一条记录所拥有的字段数量进行读取剩余记录,也就是说每一条记录的字段数量都必须和第一条记录相同
这个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}
上一篇: 编写高性能React组件-传值篇
下一篇: C#之简易计算器设计