Go Web:数据存储(2)——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}
Go Web:数据存储(2)——CSV文件的更多相关文章
- 直接把数据库中的数据保存在CSV文件中
今天突然去聊就来写一个小小的demo喽,嘿嘿 public partial class Form1 : Form { public Form1() { InitializeComponent(); } ...
- <Android基础> (六) 数据存储 Part 1 文件存储方式
第六章 数据存储 6.1 持久化技术 持久化技术指将内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失. 主要有三种方式用于简单地实现数据持久化功能:文件存储.S ...
- python3下scrapy爬虫(第九卷:scrapy数据存储进JSON文件)
将爬取数据存储在JSON文件里并不难,只需修改pipelines文件 直接看代码: 来看下结果: 中文字符恶心的很 之后我会在后卷中做出修改
- 数据存储之json文件处理和csv文件处理
什么是json: JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式.它基于 ECMAScript (w3c制定的js规范)的一个子集,采用 ...
- python爬虫#数据存储#JSON/CSV/MYSQL/MongoDB/
Json数据处理 JSON支持数据格式: 对象(字典).使用花括号. 数组(列表).使用方括号. 整形.浮点型.布尔类型还有null类型. 字符串类型(字符串必须要用双引号,不能用单引号). 多个数据 ...
- Web 端 js 导出csv文件(使用a标签)
前言 导出文件,使用最多的方式还是服务器端来处理.比如jsp 中使用response 的方式. 但是,有时候可能就想使用web 前端是否也可以把页面上的内容导出来呢? 比如说,导出页面的一个表格. 这 ...
- Android 数据存储02之文件读写
Android文件读写 版本 修改内容 日期 修改人 V1.0 原始版本 2013/2/25 skywang Android文件读写的有两种方式.一种,是通过标准的JavaIO库去读写.另一种,是通过 ...
- Android开发--数据存储之File文件存储
转载来自:http://blog.csdn.net/ahuier/article/details/10364757,并进行扩充 引言:Android开发中的数据存储方式 Android提供了5种方式存 ...
- vue.js纯前端处理如何将后台返回来的csv数据导出成csv文件
需要实现一个下载csv文件的功能,但后台没有对这个下载文件进行处理,而是将csv数据传给前台而已,需要前台做一下处理. 这是按钮的代码: <a> <el-button size=&q ...
随机推荐
- 简述Oracle IOT(Index Organized Table)
转:http://blog.itpub.net/17203031/viewspace-744477 对关系型数据库产品(RDBMS)而言,一个重要特性就是:数据信息都被组织为二维数据表,信息的表达可以 ...
- OpenCV3.30 画图函数
画图函数(Draw Functions)都放在imgpro. 例如C++中用: #include <opencv2\imgproc.hpp>
- 20145232韩文浩《网络对抗》PC平台逆向破解
shellcode注入 1.Linux下有两种基本构造攻击buf的方法:retaddr+nop+shellcode,nop+shellcode+retaddr.我们采用anything+retaddr ...
- Solr Cloud安装
1. zookeeper-3.4.10安装: zoo.cfg配置文件: dataDir=/usr/share/zookeeper/data/ clientPort=2181 server.1=10.0 ...
- winform中TextBox只能输入字母
private void txtTestPerson_KeyPress(object sender, KeyPressEventArgs e) { if ((e.KeyChar >= 'a' & ...
- 【Solidity】学习(3)
函数 重定义 不支持重定义,会在编译时候报错 pragma solidity ^0.4.0; contract test { uint public a =100; function changeA ...
- Java中main方法参数String[ ] args的使用。
我们刚开始学习java时都会被要求记住主方法(main)的写法,就像这样: public static void main(String[] args){ } public static void m ...
- 调用接口,发送https请求
调用https接口有两种方式 一:是导入证书; 证书调用https请求本人还不知道,希望看见此博客的大神给我回复. 二:是创建信任管理器. 第一步:实现X509TrustManager接口,里面的方法 ...
- git常用的命令行
git管理相关基础命令行,因为现在很多公司都用git管理代码,所以被问及的概率很大,可以用pycharm的git系统,也可以用git代码管理 $git init #初始化仓库$git branch 分 ...
- 简单 v.s. 基础
无论做平面设计还是做摄影创作,其基础都是一些比较粗浅的看似毫无用处的简单技能.例如画直线.拍挂在墙上的电视机,不一而足. 同样的现象还能在web的前端设计中看到.一堆类似小孩学绘画的标签,几个可以更改 ...