"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيف يمكنني قراءة ملفات CSV وكتابتها بكفاءة في Go باستخدام التزامن؟

كيف يمكنني قراءة ملفات CSV وكتابتها بكفاءة في Go باستخدام التزامن؟

تم النشر بتاريخ 2024-11-09
تصفح:148

How can I efficiently read and write CSV files in Go using concurrency?

قراءة وكتابة فعالة بتنسيق CSV في Go

تتضمن مهمة قراءة وكتابة ملف CSV بكفاءة في Go تحسين عمليات الإدخال / الإخراج . خذ بعين الاعتبار مقتطف التعليمات البرمجية التالي الذي يقرأ ملف CSV، ويجري عمليات حسابية على البيانات، ويكتب النتائج إلى ملف 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()
}

التحسين الرئيسي في هذا الرمز هو استخدام التزامن لمعالجة صفوف CSV واحدًا تلو الآخر. باستخدام قناة، يمكننا قراءة الصفوف من ملف CSV المدخل في goroutine وكتابة النتائج إلى ملف CSV الناتج في الروتين الرئيسي بشكل متزامن. يتجنب هذا الأسلوب تحميل الملف بأكمله في الذاكرة، مما قد يقلل بشكل كبير من استهلاك الذاكرة ويحسن الأداء.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3