# Day34 Golang 操作CSV **CVS** 是以逗號`,`及換行`\n`分隔的資料格式, 從CSV的英文(Comma-Separated Values)中就能窺出一二。 ## CSV長的怎樣 用Excel開啟一個CSV檔案 (副檔名要為.csv 而非.xlsx。 xlsx是 Microsoft Office Excel 獨有的格式) ![Execl](https://i.imgur.com/pODt30p.png) 用記事本開啟一個CSV檔案 原來就長成這樣而已 ![Notepad++](https://i.imgur.com/m0br8JG.png) (也有出現以空白字元` `、`\t` 或其他字元來做分隔,只要解析時以該字元下去做區隔就行) ## 讀取 Read CSV Golang讀檔案時會需要用到`絕對路徑`, 在這邊先取 `pwd` 當前路徑、再加上 `fileName` 檔案名稱。 ```go= var Pwd string var FilePath string var FileName = "test.csv" func init() { Pwd, _ = os.Getwd() FilePath = filepath.Join(Pwd, FileName) } func Load() { file, err := os.OpenFile(FilePath, os.O_RDONLY, 0777) // os.O_RDONLY 表示只讀、0777 表示(owner/group/other)權限 if err != nil { log.Fatalln("找不到CSV檔案路徑:", FilePath, err) } // read r := csv.NewReader(file) r.Comma = ',' // 以何種字元作分隔,預設為`,`。所以這裡可拿掉這行 for { record, err := r.Read() if err == io.EOF { break } if err != nil { log.Fatalln(err) } var a = record[0] var b = record[1] fmt.Println(a, b) } } ``` **讀取結果** ![讀取結果](https://i.imgur.com/5qW4ucu.png) ### 讀寫權限的常數 ```go= os.O_RDONLY 唯讀 os.O_WRONLY 唯寫 os.O_RDWR 讀/寫 ``` [**詳見官方文檔**](https://golang.org/pkg/os/#pkg-constants) ## 寫入 Write CSV **Write寫入單行** ```go= func Write() { file, err := os.OpenFile(FilePath, os.O_WRONLY, 0777) if err != nil { log.Fatalln("找不到CSV檔案路徑:", FilePath, err) } w := csv.NewWriter(file) x := []string{"999"} w.Write(x) w.Flush() // 把在buffer緩存中的所有資料輸出 } ``` **WriteAll寫入多行** ```go= w := csv.NewWriter(file) x := [][]string{{"999", "1"}, {"998", "997"}} w.WriteAll(x) w.Flush() // 把在buffer緩存中的所有資料輸出 ``` ### 寫入的坑 若開啟一個空白檔案寫入,不會有任何問題。 但若開啟已經有資料的CSV,再寫入的話會發生炸裂 **已有的原始資料** ![原始資料](https://i.imgur.com/H1uuX4M.png) 如果寫入以下一行資料 ```go= w := csv.NewWriter(file) x := []string{"999"} w.Write(x) w.Flush() // 把在buffer緩存中的所有資料輸出 ``` 咦~~怎麼跟我預想的結果不太一樣?! **炸裂過後** ![炸裂過後](https://i.imgur.com/uZP5moa.png) 怎麼多了一堆莫名其妙的空格? 用EXCEL開,會看不清發生了什麼事情, 但以記事本開啟的話: **資料從原本的狀態** ![原始資料](https://i.imgur.com/zrA9K7Z.png) **變成這樣** ![炸裂過後](https://i.imgur.com/fqm8p0Q.png) 也就是說,我輸入的單行的資料是`'999'\n'`,把原始資料`1,2,3,4'\n'`給蓋過去 **將最前面四個字元覆蓋掉了**,就變成`999'\n'3,4'\n' ...` 所以用Excel打開才會被解析成上方那樣的炸裂圖。 ## 附加 Append CSV 打開檔案的時候以 `O_APPEND` 模式開啟, 就能不影響舊資料,將欲寫入的資料Append在最後了。 ```go file, err := os.OpenFile(FilePath, os.O_APPEND, 0777) ``` ## 其他操作方法 取代? ```go= r, err := file.Seek(-int64(len(points)), 1) file.Truncate(0) ```