GoLang-データストレージ(上)
データストレージは、ファイルストレージ、リレーショナル・データベース(SQL)、非リレーショナル・データベース(NoSQL)の3つに分類されます.本稿では、主にファイルストレージの実現方法について説明します.
ファイルストレージは、txt読み書きなどの一般ファイル、CSVファイル、データのシーケンス化、永続化など、異なるファイルに基づいて異なるストレージ方式を実現します.
通常ファイル(txt読み書きなど)
一般ファイルの読み書きはosまたはio/ioutilパッケージを用いて実現でき、両者の実現方式は以下の通りである.
CSVファイル
CSV形式は、テキストエディタがテキストと数値からなる表データを読み書きやすくするファイル形式です.CSVの応用は非常に広く、マイクロソフトのExcelやアップルのNumbersを含むほとんどのスプレッドシートプログラムはCSVフォーマットをサポートしているため、Goを含む多くのプログラミング言語はCSVファイルデータの生成と処理が可能な関数ライブラリを提供している.Go言語では、CSVファイルはencoding/csvパッケージで操作でき、実装コードは以下の通りです.
データのシーケンス化と永続化
goのencoding/gobパケットはgobからなるストリーム(stream)を管理するために用いられ、エンコーダとデコーダとの間で交換されるバイナリデータであり、このデータはもともとシーケンス化およびデータ伝送のために設計されていたが、データの永続化に用いられ、ユーザが容易にファイルを読み書きできるようにするために、エンコーダとデコーダは一般的にプログラムのライタとリーダをそれぞれ包む.簡単に言えば、goのencoding/gobパッケージはpythonのpickleモジュールに似ており、両者が実現する機能は同じである.しかし、両者を比較すると、encoding/gobパッケージの使用方法はpythonの便利さがなく、具体的な使用過程は以下の通りであることが分かった.
ファイルストレージは、txt読み書きなどの一般ファイル、CSVファイル、データのシーケンス化、永続化など、異なるファイルに基づいて異なるストレージ方式を実現します.
通常ファイル(txt読み書きなど)
一般ファイルの読み書きはosまたはio/ioutilパッケージを用いて実現でき、両者の実現方式は以下の通りである.
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
// ioutil WriteFile
data := []byte("Hello World!
")
err := ioutil.WriteFile("data1.txt", data, 0644)
if err != nil {
panic(err)
}
// ioutil ReadFile
read1, _ := ioutil.ReadFile("data1.txt")
fmt.Print(string(read1))
// os Create
file1, _ := os.Create("data2.txt")
// defer, file1
defer file1.Close()
// file1
bytes, _ := file1.Write(data)
fmt.Printf("Wrote %d bytes to file
", bytes)
// os Open data2.txt, file2
file2, _ := os.Open("data2.txt")
defer file2.Close()
// data
read2 := make([]byte, len(data))
// file2 Read , read2
bytes, _ = file2.Read(read2)
fmt.Printf("Read %d bytes from file
", bytes)
fmt.Println(string(read2))
}
CSVファイル
CSV形式は、テキストエディタがテキストと数値からなる表データを読み書きやすくするファイル形式です.CSVの応用は非常に広く、マイクロソフトのExcelやアップルのNumbersを含むほとんどのスプレッドシートプログラムはCSVフォーマットをサポートしているため、Goを含む多くのプログラミング言語はCSVファイルデータの生成と処理が可能な関数ライブラリを提供している.Go言語では、CSVファイルはencoding/csvパッケージで操作でき、実装コードは以下の通りです.
package main
import (
"encoding/csv"
"fmt"
"os"
"strconv"
)
type Post struct {
Id int
Content string
Author string
}
func main() {
// posts.csv
csvFile, err := os.Create("posts.csv")
if err != nil {
panic(err)
}
defer csvFile.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"},}
// csv NewWriter csvFile
writer := csv.NewWriter(csvFile)
// allPosts , CSV
for _, post := range allPosts {
// strconv.Itoa(post.Id)
// line
line := []string{strconv.Itoa(post.Id), post.Content, post.Author}
// line CSV
err := writer.Write(line)
if err != nil {
panic(err)
}
}
// Flush
writer.Flush()
// ……………………………………………………………………………………… ………………………………………………………………………………………
// CSV
file, err := os.Open("posts.csv")
if err != nil {
panic(err)
}
defer file.Close()
// csv NewWriter csvFile
reader := csv.NewReader(file)
//
// FieldsPerRecord , CSV ,Go 。
// FieldsPerRecord 0, FieldsPerRecord 。
// FieldsPerRecord , , 。
reader.FieldsPerRecord = -1
//
// Read()
record, err := reader.ReadAll()
if err != nil {
panic(err)
}
//
var posts []Post
for _, item := range record {
// Id
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)
}
データのシーケンス化と永続化
goのencoding/gobパケットはgobからなるストリーム(stream)を管理するために用いられ、エンコーダとデコーダとの間で交換されるバイナリデータであり、このデータはもともとシーケンス化およびデータ伝送のために設計されていたが、データの永続化に用いられ、ユーザが容易にファイルを読み書きできるようにするために、エンコーダとデコーダは一般的にプログラムのライタとリーダをそれぞれ包む.簡単に言えば、goのencoding/gobパッケージはpythonのpickleモジュールに似ており、両者が実現する機能は同じである.しかし、両者を比較すると、encoding/gobパッケージの使用方法はpythonの便利さがなく、具体的な使用過程は以下の通りであることが分かった.
package main
import (
"bytes"
"encoding/gob"
"fmt"
"io/ioutil"
)
type Post struct {
Id int
Content string
Author string
}
func store(data interface{}, filename string) {
// buffer
// Read Write (variable-sized)
// ,bytes.Buffer 。
buffer := new(bytes.Buffer)
// buffer , encoder
encoder := gob.NewEncoder(buffer)
// data encoder( buffer)
err := encoder.Encode(data)
if err != nil {
panic(err)
}
// buffer ,
err = ioutil.WriteFile(filename, buffer.Bytes(), 0600)
if err != nil {
panic(err)
}
}
func load(data interface{}, filename string) {
// filename
raw, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
// buffer, raw buffer
buffer := bytes.NewBuffer(raw)
// buffer dec
dec := gob.NewDecoder(buffer)
// data
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.Id)
}