首頁>技術>

CSV是操作資料的常用格式。將CSV檔案匯入或匯出到Excel中亦是很常見的操作。Go的CSV包提供了資料操作介面,因此可以輕鬆地將資料寫入緩衝區,標準輸出,檔案或socket。本節將展示將資料匯入和匯出CSV格式的一些常用方法。

參考:go語言中文文件:www.topgoer.com

實踐

1.建立read_csv.go:

package csvformatimport (    "bytes"    "encoding/csv"    "fmt"    "io"    "strconv")// Movie用來儲存CSV解析後的內容type Movie struct {    Title    string    Director string    Year     int}// ReadCSV 展示瞭如何處理CSV// 接收的引數透過io.Reader傳入func ReadCSV(b io.Reader) ([]Movie, error) {    //返回的是csv.Reader    r := csv.NewReader(b)    // 分隔符和註釋是csv.Reader結構體中的欄位    r.Comma = ';'    r.Comment = '-'    var movies []Movie    // 讀取並返回一個字串切片和錯誤資訊    // 我們也可以將其用於字典鍵或其他形式的查詢    // 此處忽略了返回的切片 目的是跳過csv首行標題    _, err := r.Read()    if err != nil && err != io.EOF {        return nil, err    }    // 迴圈直到全部處理完畢    for {        record, err := r.Read()        if err == io.EOF {            break        } else if err != nil {            return nil, err        }        year, err := strconv.ParseInt(record[2], 10, 64)        if err != nil {            return nil, err        }        m := Movie{record[0], record[1], int(year)}        movies = append(movies, m)    }    return movies, nil}// AddMoviesFromText 將字串按 CSV 格式解析func AddMoviesFromText() error {    in := `- first our headersmovie title;director;year released- then some dataGuardians of the Galaxy Vol. 2;James Gunn;2017Star Wars: Episode VIII;Rian Johnson;2017`    b := bytes.NewBufferString(in)    m, err := ReadCSV(b)    if err != nil {        return err    }    fmt.Printf("%#v\n", m)    return nil}

2.建立 write_csv.go:

package csvformatimport (    "bytes"    "encoding/csv"    "io"    "os")// 結構體Book有Author和Title兩個欄位type Book struct {    Author string    Title  string}// Books是Book的切片型別type Books []Book// ToCSV將Books寫入傳進來的 io.Writer// 返回任何可能發生的錯誤func (books *Books) ToCSV(w io.Writer) error {    n := csv.NewWriter(w)    err := n.Write([]string{"Author", "Title"})    if err != nil {        return err    }    for _, book := range *books {        err := n.Write([]string{book.Author, book.Title})        if err != nil {            return err        }    }    n.Flush()    return n.Error()}// WriteCSVOutput 初始化Books並呼叫ToCSV// 並寫入到標準輸出func WriteCSVOutput() error {    b := Books{        Book{            Author: "F Scott Fitzgerald",            Title:  "The Great Gatsby",        },        Book{            Author: "J D Salinger",            Title:  "The Catcher in the Rye",        },    }    return b.ToCSV(os.Stdout)}// WriteCSVBuffer 初始化Books並呼叫ToCSV// 並寫入到bytes.Buffersfunc WriteCSVBuffer() (*bytes.Buffer, error) {    b := Books{        Book{            Author: "F Scott Fitzgerald",            Title:  "The Great Gatsby",        },        Book{            Author: "J D Salinger",            Title:  "The Catcher in the Rye",        },    }    w := &bytes.Buffer{}    err := b.ToCSV(w)    return w, err}

3.建立main.go:

import (    "fmt"    "github.com/agtorre/go-cookbook/chapter1/csvformat")func main() {    if err := csvformat.AddMoviesFromText(); err != nil {        panic(err)    }    if err := csvformat.WriteCSVOutput(); err != nil {        panic(err)    }    buffer, err := csvformat.WriteCSVBuffer()    if err != nil {        panic(err)    }    fmt.Println("Buffer = ", buffer.String())}

4.執行main.go,這會輸出:

[]csvformat.Movie{csvformat.Movie{Title:"Guardians of the Galaxy Vol. 2", Director:"James Gunn", Year:2017}, csvformat.Movie{Title:"Star Wars: Episode VIII", Director:"Rian Johnson", Year:2017}}Author,TitleF Scott Fitzgerald,The Great GatsbyJ D Salinger,The Catcher in the RyeBuffer =  Author,TitleF Scott Fitzgerald,The Great GatsbyJ D Salinger,The Catcher in the Rye
說明

為了探索CSV格式操作,我們首先將資料表示為結構。在Go中將資料格式化為結構非常有用,這會使目標封裝和編碼等變得相對簡單。 我們的示例中使用自定義的Movie結構。它所屬的函式接收io.Reader介面作為引數以使CSV資料輸入時更加靈活——檔案或緩衝區都可以輸入進來。接下來,我們使用傳入的資料來建立並填充Movie結構,我們還向CSV解析器添加了 ; 作為分隔符 - 作為註釋行。

接下來,我們以類似的方式探索CSV格式的寫入操作,我們初始化一系列Books,然後將CSV格式的特定book寫入io.Writer介面,同樣的,目標可以是檔案,標準輸出或緩衝區。

CSV包是一個很棒的例子,它說明了為什麼你需要考慮要將Go中的資料流視為實現通用介面。透過細微的調整,我們可以輕鬆更改資料的來源和目的地,同時不影響操作CSV資料,並且無需使用過多的記憶體或時間。例如,可以一次從一個數據流中讀取一個記錄,並以迴圈的形式將修改的格式寫入單獨的流。這樣做不會佔用大量記憶體或處理器。

稍後,在探索資料管道和工作池時,你將看到如何組合這些想法以及如何並行處理這些流。

9
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 時序資料庫InfluxDB引擎淺析