Тип csv.Reader

Тип csv.Reader предназначен для чтения данных в формате CSV (Comma-Separated Values). Он позволяет построчно читать записи из входного потока, автоматически разбивая строки на поля с учетом разделителей и правил экранирования. Основные методы типа: Read, который читает одну запись, и ReadAll, который читает все записи сразу.

Создание ридера

Для создания нового ридера используется функция csv.NewReader, которая принимает io.Reader и возвращает указатель на csv.Reader. В качестве источника данных можно использовать файл, строку или любой другой объект, реализующий интерфейс io.Reader.

gopackage main

import (
  "encoding/csv"
  "fmt"
  "strings"
)

func main() {
  data := "John,25,Engineer\nJane,30,Designer"
  reader := csv.NewReader(strings.NewReader(data))
  fmt.Println(reader)
}

Результат выполнения кода:

go&{%!(*strings.Reader=&{0xc00008e1e0 0 -1 0 0}) , false false false false [] 0}

Метод Read

Метод Read читает следующую запись из CSV-данных и возвращает срез строк ([]string) с полями этой записи. Если достигнут конец файла, метод возвращает ошибку io.EOF. При возникновении ошибки парсинга возвращается ошибка типа csv.ParseError.

gopackage main

import (
  "encoding/csv"
  "fmt"
  "io"
  "strings"
)

func main() {
  data := "John,25,Engineer\nJane,30,Designer"
  reader := csv.NewReader(strings.NewReader(data))

  for {
    record, err := reader.Read()
    if err == io.EOF {
      break
    }
    if err != nil {
      fmt.Printf("Error: %v\n", err)
      break
    }
    fmt.Printf("Record: %v\n", record)
  }
}

Результат выполнения кода:

go"Record: [John 25 Engineer]"
"Record: [Jane 30 Designer]"

Метод ReadAll

Метод ReadAll читает все оставшиеся записи из CSV-данных и возвращает срез срезов строк ([][]string). Этот метод удобен, когда нужно загрузить все данные в память для дальнейшей обработки. При возникновении ошибки возвращается прочитанная до ошибки часть данных и сама ошибка.

gopackage main

import (
  "encoding/csv"
  "fmt"
  "strings"
)

func main() {
  data := "John,25,Engineer\nJane,30,Designer\nBob,28,Manager"
  reader := csv.NewReader(strings.NewReader(data))

  records, err := reader.ReadAll()
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  for i, record := range records {
    fmt.Printf("Record %d: %v\n", i, record)
  }
}

Результат выполнения кода:

go"Record 0: [John 25 Engineer]"
"Record 1: [Jane 30 Designer]"
"Record 2: [Bob 28 Manager]"

Настройка разделителя

По умолчанию ридер использует запятую в качестве разделителя полей. Поле Comma структуры csv.Reader позволяет изменить разделитель на любой другой символ, например, точку с запятой или табуляцию. Разделитель должен быть одним символом и не может быть кавычкой, переводом строки или обратной косой чертой.

gopackage main

import (
  "encoding/csv"
  "fmt"
  "strings"
)

func main() {
  data := "John;25;Engineer\nJane;30;Designer"
  reader := csv.NewReader(strings.NewReader(data))
  reader.Comma = ';'

  records, err := reader.ReadAll()
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  for i, record := range records {
    fmt.Printf("Record %d: %v\n", i, record)
  }
}

Результат выполнения кода:

go"Record 0: [John 25 Engineer]"
"Record 1: [Jane 30 Designer]"

Обработка заголовков

Часто CSV-файлы содержат строку заголовков в первой строке. Поле Reader не имеет встроенной поддержки заголовков, но их легко обработать, прочитав первую строку отдельно. Это позволяет затем использовать заголовки для доступа к данным по имени колонки.

gopackage main

import (
  "encoding/csv"
  "fmt"
  "strings"
)

func main() {
  data := "Name,Age,Position\nJohn,25,Engineer\nJane,30,Designer"
  reader := csv.NewReader(strings.NewReader(data))

  headers, err := reader.Read()
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  records, err := reader.ReadAll()
  if err != nil {
    fmt.Printf("Error: %v\n", err)
    return
  }

  fmt.Printf("Headers: %v\n", headers)
  for i, record := range records {
    fmt.Printf("Record %d: %v\n", i, record)
  }
}

Результат выполнения кода:

go"Headers: [Name Age Position]"
"Record 0: [John 25 Engineer]"
"Record 1: [Jane 30 Designer]"

Смотрите также

  • тип csv.Writer,
    который используется для записи данных в формате CSV
  • функцию csv.NewReader,
    которая создает новый экземпляр csv.Reader
  • метод csv.Reader.Read,
    который читает одну запись из CSV-данных
  • метод csv.Reader.ReadAll,
    который читает все записи из CSV-данных