파일 저장
- 메모리에 데이터를 저장하는게 빠르지만 휘발성 데이터임 (임시로 저장)
- 메모리에 저장된 데이터를 비 휘발성 저장 장치(하드)에 저장시키자
- csv는 텍스트포맷(콤마로 구분), gob는 바이너리 포맷 으로 serializing, cahing할 때 효과적 이라 함
CSV 읽기 쓰기
1. 데이터 정의 및 csv파일 생성
- 게시판 어플리케이션을 만든다 생각했을 떄, 아래와 같이 struct를 정의한다.
type Post struct {
Id int
Content string
Author string
}
- post파일을 저장할 csv파일을 생성해준다. (defer와 panic은 추후 공부하자)
csvFile, err := os.Create("posts.csv")
if err != nil {
panic(err)
}
defer csvFile.Close()
2. csv파일에 저장할 임의의 데이터를 생성하고, csv파일에 저장한다.
- csv에 정의할 데이터를 만들어 준다.
allPosts := []Post {
{Id: 1, Content: "Hello World!", Author: "John"},
{Id: 2, Content: "안녕하세요!", Author: "창종"},
{Id: 3, Content: "Aloha", Author: "Anna"},
{Id: 4, Content: "I'am John", Author: "John"},
}
- csv.NewWriter로 writer를 생성하고, csv에 저장할 string array에 데이터를 담아 writer에 데이터를 저장한다. Flush 함수를 호출을 하여 버퍼를 비워 작성한다.
writer := csv.NewWriter(csvFile)
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()
3. csv 파일 읽기
- csv 파일을 읽고, reader를 생성하고 FieldsPerRecode 값을 설정해준다. (양수: 정확한 필드의 수, 음수: 필드의 수가 부족해도 됨)
file, err := os.Open("posts.csv")
if err != nil {
panic(err)
}
defer file.Close()
reader :=csv.NewReader(file)
reader.FieldsPerRecord = -1
record, err := reader.ReadAll()
if err != nil {
panic(err)
}
4. 읽은 record 순회
- 읽은 데이터(record)를 순회하며 객체를 생성하여 데이터를 메모리에 저장한다.
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)
}
gob 패키지 다루기
1. store: data interface를입력받아 binray로 encoding
- gob 패키지는 바이너리 데이터인 gob의 스트림을 관리하며 인코더와 디코더 간 변화를 지원(일반 파일io랑 비슷)
- data --> endcoding --> buffer 데이터를 파일에 작성
func store(data interface{}, filename string) {
buffer := new(bytes.Buffer)
encoder := gob.NewEncoder(buffer)
err := encoder.Encode(data)
if err != nil {
panic(err)
}
err = ioutil.WriteFile(filename, buffer.Bytes(), 0600)
if err != nil {
panic(err)
}
}
2. load: encoding한 파일을 다시 decoding하여 interface에 저장
- ioutil로 raw 파일을 읽고, decoding
- raw --> decoding --> data
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)
}
}
test code
- 간단한 post 데이터를 store, load해보고 출력하는 코드
func main() {
post := Post{Id: 1, Content: "Hello World!", Author: "dksshddl"}
store(post, "post1")
var postRead Post
load(&postRead, "post1")
fmt.Println(postRead)
}
어려운 부분은 아닌데, 파일을 다룰때 defer, panic 함수의 구체적 사용법, 이유등을 더 공부해야 겠다.
'Language > Go' 카테고리의 다른 글
[Go] Go 사용하기(코드 구조, package) (0) | 2020.01.23 |
---|---|
[Go] - web programming : postgresSQL연결, CRUD사용해보기 (1) | 2020.01.20 |
[Go] - web programming : 상황 인지, XSS 공격 막기 (0) | 2020.01.16 |
[Go] - web programming : 액션 (0) | 2020.01.16 |
[Go] - web programming : 템플릿과 템플릿 엔진 (0) | 2020.01.15 |