Go 中高效的 CSV 讀寫
Go 中高效的 CSV 讀寫
package main
import (
"encoding/csv"
"fmt"
"log"
"os"
"strconv"
)
func ReadRow(r *csv.Reader) (map[string]string, error) {
record, err := r.Read()
if err == io.EOF {
return nil, io.EOF
}
if err != nil {
return nil, err
}
m := make(map[string]string)
for i, v := range record {
m[strconv.Itoa(i)] = v
}
return m, nil
}
func main() {
// load data csv
csvFile, err := os.Open("./path/to/datafile.csv")
if err != nil {
log.Fatal(err)
}
defer csvFile.Close()
// create channel to process rows concurrently
recCh := make(chan map[string]string, 10)
go func() {
defer close(recCh)
r := csv.NewReader(csvFile)
if _, err := r.Read(); err != nil { //read header
log.Fatal(err)
}
for {
rec, err := ReadRow(r)
if err == io.EOF {
return // no more rows to read
}
if err != nil {
log.Fatal(err)
}
recCh <- rec
}
}()
// write results to a new csv
outfile, err := os.Create("./where/to/write/resultsfile.csv"))
if err != nil {
log.Fatal("Unable to open output")
}
defer outfile.Close()
writer := csv.NewWriter(outfile)
for record := range recCh {
time := record["0"]
value := record["1"]
// get float values
floatValue, err := strconv.ParseFloat(value, 64)
if err != nil {
log.Fatal("Record: %v, Error: %v", floatValue, err)
}
// calculate scores; THIS EXTERNAL METHOD CANNOT BE CHANGED
score := calculateStuff(floatValue)
valueString := strconv.FormatFloat(floatValue, 'f', 8, 64)
scoreString := strconv.FormatFloat(prob, 'f', 8, 64)
//fmt.Printf("Result: %v\n", []string{time, valueString, scoreString})
writer.Write([]string{time, valueString, scoreString})
}
writer.Flush()
}
package main
進口 (
“編碼/csv”
“FMMT”
"紀錄"
"作業系統"
“strcon”
)
func ReadRow(r *csv.Reader) (map[string]string, error) {
記錄, err := r.Read()
如果錯誤 == io.EOF {
返回零,io.EOF
}
如果錯誤! = nil {
回傳零,錯誤
}
m := make(地圖[字串]字串)
對於 i, v := 範圍記錄 {
m[strconv.Itoa(i)] = v
}
返回 m,零
}
函數主() {
// 載入資料csv
csvFile, err := os.Open("./path/to/datafile.csv")
如果錯誤! = nil {
日誌.致命(錯誤)
}
延後 csvFile.Close()
// 建立頻道來同時處理行
recCh := make(chan 映射[字串]字串, 10)
去函數(){
延後關閉(recCh)
r := csv.NewReader(csvFile)
如果 _, err := r.Read(); err != nil { //讀取標題
日誌.致命(錯誤)
}
為了 {
記錄,錯誤:= ReadRow(r)
如果錯誤 == io.EOF {
return // 不再需要讀取行
}
如果錯誤! = nil {
日誌.致命(錯誤)
}
記錄此程式碼的主要改進是使用並發性一次處理一個 CSV 行。透過使用通道,我們可以在 Goroutine 中從輸入 CSV 檔案中讀取行,並將結果同時寫入主例程中的輸出 CSV 檔案中。這種方法避免了將整個檔案載入到記憶體中,可以顯著減少記憶體消耗並提高效能。 免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3