<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go 數(shù)據(jù)存儲篇(三):通過 CSV 格式讀寫文本數(shù)據(jù)

          共 3883字,需瀏覽 8分鐘

           ·

          2020-09-10 20:45

          上篇教程中,給大家演示了如何通過 JSON 編碼存儲文本數(shù)據(jù)到磁盤文件,除此之外,Go 語言還提供了對 CSV 格式文件的支持,CSV 文件本質(zhì)上雖然就是文本格式數(shù)據(jù),不過可以兼容 Excel 表格,這樣一來就可以極大方便我們對大批量數(shù)據(jù)進行管理。

          使用 encoding/csv 包讀寫 CSV 文件

          在 Go 語言中,可以通過官方提供的 encoding/csv 包來操作 CSV 文件的寫入和讀取,我們新建一個 csv.go 文件,并編寫一段示例代碼如下:

          package?main

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

          type?Tutorial?struct?{
          ????Id?int
          ????Title?string
          ????Summary?string
          ????Author?string
          }

          func?main()??{
          ????//?創(chuàng)建一個?tutorials.csv?文件
          ????csvFile,?err?:=?os.Create("tutorials.csv")
          ????if?err?!=?nil?{
          ????????panic(err)
          ????}
          ????defer?csvFile.Close()

          ????//?初始化字典數(shù)據(jù)
          ????tutorials?:=?[]Tutorial{
          ????????Tutorial{Id:?1,?Title:?"Go?入門編程",?Summary:?"Go?基本語法和使用示例",?Author:?"學(xué)院君"},
          ????????Tutorial{Id:?2,?Title:?"Go?Web?編程",?Summary:?"Go?Web?編程入門指南",?Author:?"學(xué)院君"},
          ????????Tutorial{Id:?3,?Title:?"Go?并發(fā)編程",?Summary:?"通過并發(fā)編程提升性能",?Author:?"學(xué)院君"},
          ????????Tutorial{Id:?4,?Title:?"Go?微服務(wù)開發(fā)",?Summary:?"基于?go-micro?框架開發(fā)微服務(wù)",?Author:?"學(xué)院君"},
          ????}

          ????//?初始化一個?csv?writer,并通過這個?writer?寫入數(shù)據(jù)到?csv?文件
          ????writer?:=?csv.NewWriter(csvFile)
          ????for?_,?tutorial?:=?range?tutorials?{
          ????????line?:=?[]string{
          ????????????strconv.Itoa(tutorial.Id),??//?將?int?類型數(shù)據(jù)轉(zhuǎn)化為字符串
          ????????????tutorial.Title,
          ????????????tutorial.Summary,
          ????????????tutorial.Author,
          ????????}
          ????????//?將切片類型行數(shù)據(jù)寫入?csv?文件
          ????????err?:=?writer.Write(line)
          ????????if?err?!=?nil?{
          ????????????panic(err)
          ????????}
          ????}
          ????//?將?writer?緩沖中的數(shù)據(jù)都推送到?csv?文件,至此就完成了數(shù)據(jù)寫入到?csv?文件
          ????writer.Flush()

          ????//?打開這個?csv?文件
          ????file,?err?:=?os.Open("tutorials.csv")
          ????if?err?!=?nil?{
          ????????panic(err)
          ????}
          ????defer?file.Close()

          ????//?初始化一個?csv?reader,并通過這個?reader?從?csv?文件讀取數(shù)據(jù)
          ????reader?:=?csv.NewReader(file)
          ????//?設(shè)置返回記錄中每行數(shù)據(jù)期望的字段數(shù),-1?表示返回所有字段
          ????reader.FieldsPerRecord?=?-1
          ????//?通過?readAll?方法返回?csv?文件中的所有內(nèi)容
          ????record,?err?:=?reader.ReadAll()
          ????if?err?!=?nil?{
          ????????panic(err)
          ????}

          ????//?遍歷從?csv?文件中讀取的所有內(nèi)容,并將其追加到?tutorials2?切片中
          ????var?tutorials2?[]Tutorial
          ????for?_,?item?:=?range?record?{
          ????????id,?_?:=?strconv.ParseInt(item[0],?0,?0)
          ????????tutorial?:=?Tutorial{Id:?int(id),?Title:?item[1],?Summary:?item[2],?Author:?item[3]}
          ????????tutorials2?=?append(tutorials,?tutorial)
          ????}

          ????//?打印?tutorials2?的第一個元素驗證?csv?文件寫入/讀取是否成功
          ????fmt.Println(tutorials2[0].Id)
          ????fmt.Println(tutorials2[0].Title)
          ????fmt.Println(tutorials2[0].Summary)
          ????fmt.Println(tutorials2[0].Author)
          }

          可以看到新建文件、打開文件、關(guān)閉文件和上篇教程操作普通的磁盤文件并無區(qū)別,不過這里為了支持通過 CSV 格式寫入和讀取文件,我們在文件句柄之上套了一層 CSV Writer 和 CSV Reader,這有點像適配器模式,然后我們就可以通過 CSV Writer 寫入數(shù)據(jù)到 CSV 文件,通過 CSV Reader 讀取 CSV 文件了:

          ...

          //?初始化一個?csv?writer,并通過這個?writer?寫入數(shù)據(jù)到?csv?文件
          writer?:=?csv.NewWriter(csvFile)

          ...

          //?初始化一個?csv?reader,并通過這個?reader?從?csv?文件讀取數(shù)據(jù)
          reader?:=?csv.NewReader(file)??

          ...

          除了 CSV 之外,Go 官方提供的 encoding 包還提供了對其他格式文件編解碼的支持,比如 JSON、XML、Gob 等:


          使用方法了操作 CSV 文件一致,這也是 Go 語言設(shè)計之美的體現(xiàn),通過接口與組合的方式可以很方便的構(gòu)建起復(fù)雜的業(yè)務(wù)功能,感興趣的同學(xué)可以去看下 Go 官方的 io 包實現(xiàn)源碼。

          另外,這里也可以體現(xiàn)出通過 os 包獲取文件句柄進行操作相較于 ioutil 讀寫文件的優(yōu)勢:可以在文件句柄上套其他處理器進行更加靈活、復(fù)雜的操作,而 ioutil 包只能簡單進行數(shù)據(jù)寫入與讀取而已。

          關(guān)于上述代碼的實現(xiàn)細節(jié),都已經(jīng)通過詳細的注釋標注了,我們重點關(guān)注如何將數(shù)據(jù)寫入 CSV 文件,以及如何從 CSV 文件讀取數(shù)據(jù)即可。

          運行上述代碼,返回結(jié)果如下,說明 CSV 文件寫入和讀取成功:

          當然,你也可以在此基礎(chǔ)上擴展出 CSV 文件數(shù)據(jù)的增刪改查功能,感興趣的同學(xué)可以自己嘗試下,這里就具體展開了。

          使用不同軟件預(yù)覽 CSV 文件

          除了通過代碼驗證之外,還可以直接打開 csv.go 同級目錄下生成的 tutorials.csv 文件,這就是一個純文本文件,只是不同字段之間用逗號分隔,不同記錄之間用換行符分隔而已:


          在 Mac 系統(tǒng)中,你可以通過 Numbers 應(yīng)用打開這個文件進行預(yù)覽,格式化后的數(shù)據(jù)就好看多了:

          在 Windows 中,可以通過 Excel 軟件打開這個文件,但是現(xiàn)在看到的是亂碼數(shù)據(jù):

          這是因為 Excel 默認并不是 UTF-8 編碼,因此要解決這個亂碼問題,可以在對應(yīng)的 CSV 文件寫入 UTF-8 BOM 頭,告知 Excel 通過 UTF-8 編碼打開這個文件:

          ...

          //?寫入?UTF-8?BOM,防止中文亂碼
          csvFile.WriteString("\xEF\xBB\xBF")

          //?初始化一個?csv?writer,并通過這個?writer?寫入數(shù)據(jù)到?csv?文件
          writer?:=?csv.NewWriter(csvFile)

          ...

          再次運行程序,通過 Excel 打開 tutorials.csv,就可以看到正常渲染的數(shù)據(jù)了:

          關(guān)于 Excel 文件的讀取和寫入,學(xué)院君就簡單介紹到這里,這里留一個課后作業(yè),參考 encoding/csv 包讀寫 CSV 文件的方式,試著編寫一段使用 encoding/json 包讀寫 JSON 文件的代碼并正常運行起來,看看生成的文件是否符合預(yù)期。

          (全文完)




          推薦閱讀



          學(xué)習(xí)交流 Go 語言,掃碼回復(fù)「進群」即可


          站長 polarisxu

          自己的原創(chuàng)文章

          不限于 Go 技術(shù)

          職場和創(chuàng)業(yè)經(jīng)驗


          Go語言中文網(wǎng)

          每天為你

          分享 Go 知識

          Go愛好者值得關(guān)注



          瀏覽 42
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  www.精品在线播放国产区 | 国产一a毛一a免费观看 | 国产伦理久久精品久久久久 | 青青草狠狠操 | 亚洲精品久久久久久久久久久久久久 |