存储数据_文件读写

数据存储

存储在内存中

package main

import "fmt"

type Post struct {
	Id      int
	Content string
	Author  string
	/*
		 程序会使用Post struct来表示应用中的帖子,并把结构存在内存中

		Post struct最主要的数据是帖子的内容,用户也可以通过唯一ID或者Author获取帖子。
		程序会通过讲一个代表帖子的键映射到实际的Post结构来存储多个帖子,
	*/
}

// 	为了提供两种不同的方法来方法来方位帖子, 程序分别使用了两个map来创建不同的map
/*
   程序使用两个变量来存储map,PostById将帖子的唯一Id映射值指向帖子的指针;
   PostByAuthor将通过作者名字映射到一个slice, 不管是PostById 还是PostByAuthor ,
   他们映射的都是指向帖子的指针而不是帖子本身; 这样做可以确保程序无论是通过Id还是通过作者的名字来获取帖子
   得到的都是相同的帖子,而不是帖子的副本
*/
var PostById map[int]*Post
var PostByAuthor map[string][]*Post

func store(post Post) {
	PostById[post.Id] = &post
	PostByAuthor[post.Author] = append(PostByAuthor[post.Author], &post)

	/*
	   store函数会将一个指向帖子的指针分别存到PostById变量和PostByAuthor变量里

	*/

}

func main() {
	PostById = make(map[int]*Post)

	PostByAuthor = make(map[string][]*Post)

	post1 := Post{Id: 1, Content: "hello world by 张三.", Author: "张三"}
	post2 := Post{Id: 2, Content: "hello world by 李四.", Author: "李四"}
	post3 := Post{Id: 3, Content: "hello world by 王五.", Author: "王五"}
	post4 := Post{Id: 4, Content: "hello world by xxxx.", Author: "xxxx"}

	store(post1)
	store(post2)
	store(post3)
	store(post4)

	fmt.Println(PostById[1])
	fmt.Println(PostById[2])
	for _, post := range PostByAuthor["张三"] {
		fmt.Println(post)
	}

}

读写文件

package main

import (
	"fmt"
	"io/ioutil"
	"os"
)

func main() {
	data := []byte("Hello World!
")

	// -----------------  ioutil.WriteFile ReadFile 读写文件 ----------------------
	err := ioutil.WriteFile("data1", data, 0644)
	if err != nil {
		panic(err)
	}
	// ReadFile WriteFile函数对文件进行读取和写入
	read1, _ := ioutil.ReadFile("data1")
	fmt.Println(string(read1))
	/*
	   ioutil.WriteFile 需要文件名 写入的数据 设置文件的权限
	   ioutil.ReadFile 只需要传入文件名即可

	   无论是传递给WriteFile的数据,还是ReadFile返回的数据,都是由一个字节组成的切片
	*/

	// 通过File 结构对文件进行读取和写入
	file1, _ := os.Create("data2")
	defer file1.Close()
	bytes, _ := file1.Write(data)
	fmt.Printf("写入数据 %d bytes to file
", bytes)
	
	
	

	// -------------------------- File 读写文件 ---------------------------------
	file2, _ := os.Open("data2")
	defer file2.Close()
	// defer 语句可以将给定的函数第阿勇推到一个占里,保存在栈中调用会在函数返回后执行

	read2 := make([]byte, len(data))
	bytes, _ = file2.Read(read2)

	fmt.Printf("读取数据 %d bytes to file
", bytes)
	fmt.Println(string(bytes))
	
}

CSV

package main

import (
	"encoding/csv"
	"fmt"
	"os"
	"strconv"
)

type Post struct {
	Id      int
	Content string
	Author  string
}

func main() {
	// -------------------- 写 ---------------
	// 创建一个csv文件
	csv_file, err := os.Create("posts.csv")
	if err != nil {
		panic(err)
	}
	defer csv_file.Close()

	allPosts := []Post{
		Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"},
		Post{Id: 2, Content: "Bonjour Monde!", Author: "Pierre"},
		Post{Id: 3, Content: "Hola Mundo!", Author: "Pedro"},
		Post{Id: 4, Content: "Greetings Earthlings!", Author: "Sau Sheong"},
	}
	writer := csv.NewWriter(csv_file)

	for _, post := range allPosts {
		line := []string{strconv.Itoa(post.Id), post.Content, post.Author}
		err := writer.Write(line)
		if err != nil {
			panic(err)
		}
	}

	writer.Flush()

	// -------------------- 读 ------------
	//	打开csv文件
	file, err := os.Open("posts.csv")
	if err != nil {
		panic(err)
	}

	defer file.Close()

	// 读取
	reader := csv.NewReader(file)
	// 即使读取器在读取发现记录(record) 里缺少某些字段时,go会抛出错误,如果设置为负数就不会
	reader.FieldsPerRecord = -1

	record, err := reader.ReadAll()
	if err != nil {
		panic(err)
	}
	var posts []Post
	for _, item := range record {
		id, _ := strconv.ParseInt(item[0], 0, 0)
		post := Post{Id: int(id), Content: item[1], Author: item[2]}
		posts = append(posts, post)
	}

	fmt.Println(posts[0].Id)
	fmt.Println(posts[0].Content)
	fmt.Println(posts[0].Author)

}

gob 二进制文件

package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"io/ioutil"
)

type Post struct {
	Id      int
	Content string
	Author  string
}

func store(data interface{}, filename string) {
	/*
		第一个参数是空接口, 第二是文件名(二进制文件名)
	*/

	// bytes.Buffer 这个实际上就是拥有一个Read和Write方法的可变长度(variable-sized)字节缓冲区,
	// bytes.Buffer即是读取器也是写入器
	buffer := new(bytes.Buffer)

	// store函数会把缓冲区传递给NewEncoder函数,一次来创建出gob编码器,
	encoder := gob.NewEncoder(buffer)
	// 调用解码器Encode方法将数据(Post struct)编码到缓冲区里,
	err := encoder.Encode(data)
	if err != nil {
		panic(err)
	}
	// 最后再将缓冲区中已编码的数据写入文件
	err = ioutil.WriteFile(filename, buffer.Bytes(), 0600)
	if err != nil {
		panic(err)
	}
}

func load(data interface{}, filename string) {
	raw, err := ioutil.ReadFile(filename)
	if err != nil {
		panic(err)
	}
	buffer := bytes.NewBuffer(raw)
	dec := gob.NewDecoder(buffer)
	err = dec.Decode(data)
	if err != nil {
		panic(err)
	}
}

func main() {
	post := Post{Id: 1, Content: "Hello World!", Author: "Sau Sheong"}
	store(post, "post1")
	var postRead Post
	load(&postRead, "post1")
	fmt.Println(postRead)
}

原文地址:https://www.cnblogs.com/zrdpy/p/8619023.html