首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

encoding/csv

  • import "encoding/csv"
  • 概述
  • 索引
  • 示例

概述

Csv 包读取和写入逗号分隔值(CSV) 文件。CSV 文件有很多种,该软件包支持 RFC 4180 中描述的格式。

一个 csv 文件包含每个记录一个或多个字段的零个或多个记录。每条记录由换行符分隔。最后的记录可以选择跟随一个换行符。

field1,field2,field3

白色空间被视为一个域的一部分。

在换行符被无声删除之前,回车返回。

空白行被忽略。只有空白字符的行(不包括结尾换行符)不被视为空白行。

以引号字符开头和结尾的字段称为引用字段。开始和结束引号不是字段的一部分。

来源:

normal string,"quoted-field"

结果在这些领域

{`normal string`, `quoted-field`}

在引用字段中,引号字符后跟第二个引号字符被视为单引号。

"the ""word"" is true","a ""quoted-field"""

结果是

{`the "word" is true`, `a "quoted-field"`}

换行符和逗号可以包含在引用字段中

"Multi-line
field","comma is ,"

结果是

{`Multi-line
field`, `comma is ,`}

索引

  • 变量
  • type ParseError
  • func (e *ParseError) Error() string
  • type Reader
  • func NewReader(r io.Reader) *Reader
  • func (r *Reader) Read() (record []string, err error)
  • func (r *Reader) ReadAll() (records [][]string, err error)
  • type Writer
  • func NewWriter(w io.Writer) *Writer
  • func (w *Writer) Error() error
  • func (w *Writer) Flush()
  • func (w *Writer) Write(record []string) error
  • func (w *Writer) WriteAll(records [][]string) error

示例

Reader Reader.ReadAll Reader(Options) Writer Writer.WriteAll

包文件

变量

这些是可以在 ParseError.Error 中返回的错误

var (
        ErrTrailingComma = errors.New("extra delimiter at end of line") // 不再使用
        ErrBareQuote     = errors.New("bare \" in non-quoted-field")
        ErrQuote         = errors.New("extraneous \" in field")
        ErrFieldCount    = errors.New("wrong number of fields in line")
)

type ParseError(查看源代码)

解析错误返回 ParseError。第一行是1。第一列是0。

type ParseError struct {
        Line   int   // 发生错误的行
        Column int   // 发生错误的列(符文索引)
        Err    error // 实际的错误
}

func (*ParseError) Error(查看源代码)

func (e *ParseError) Error() string

Reader 从 CSV 编码的文件中读取记录。

正如 NewReader 返回的那样,Reader 期望符合 RFC 4180 的输入。可以在第一次调用 Read 或 ReadAll 之前更改导出的字段以定制细节。

type Reader struct {
        // 逗号是字段分隔符。
        // 它由NewReader设置为逗号(',')。
        Comma rune
        // 注释(如果不是0)是注释字符。 以...开头的行
        // 不带前置空格的注释字符将被忽略。
        // 使用前导空格,Comment字符成为其中的一部分
        // 字段,即使TrimLeadingSpace为true。
        Comment rune
        // FieldsPerRecord是每条记录的预期字段数。
        // 如果FieldsPerRecord为正数,则Read需要每条记录
        // 拥有给定数量的字段。 如果FieldsPerRecord为0,则Read将其设置为
        // 第一条记录中的字段数,以便将来的记录必须
        // 具有相同的字段数。 如果FieldsPerRecord为负数,则不进行检查
        // 制作和记录可能有可变数量的字段。
        FieldsPerRecord int
        // 如果LazyQuotes为true,则引号可能出现在不带引号的字段和
        // 非加倍引号可能出现在引用字段中。
        LazyQuotes    bool
        TrailingComma bool // 忽略; 这里是为了向后兼容
        // 如果TrimLeadingSpace为true,则忽略字段中的前导空格。
        // 即使字段分隔符(逗号)是空白区域,也会执行此操作。
        TrimLeadingSpace bool
        // ReuseRecord控制对Read的调用是否可以返回切片共享
        // 前一个调用的返回切片的后备数组以提高性能。
        // 默认情况下,每次调用Read都会返回调用者拥有的新分配的内存。
        ReuseRecord bool
        // 包含已过滤或未导出的字段
}

示例

package main

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

func main() {
	in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
	r := csv.NewReader(strings.NewReader(in))

	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		fmt.Println(record)
	}
}

示例(Options)

此示例显示如何配置 csv.Reader 以处理其他类型的 CSV 文件。

package main

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

func main() {
	in := `first_name;last_name;username
"Rob";"Pike";rob
# lines beginning with a # character are ignored
Ken;Thompson;ken
"Robert";"Griesemer";"gri"
`
	r := csv.NewReader(strings.NewReader(in))
	r.Comma = ';'
	r.Comment = '#'

	records, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(records)
}

func NewReader(查看源代码)

func NewReader(r io.Reader) *Reader

NewReader 返回一个新的从 r 读取的 Reader。

func (*Reader) Read(查看源代码)

func (r *Reader) Read() (record []string, err error)

读取从r读取一个记录(一段字段)。如果记录具有意外数量的字段,则 Read 将返回记录以及错误 ErrFieldCount。除此之外,Read 总是返回一个非零记录或一个非零错误,但不是两者都有。如果没有数据需要读取,则读取返回 nil,io.EOF。如果 ReuseRecord 为 true,则可以在多次调用 Read 之间共享返回的切片。

func (*Reader) ReadAll(查看源代码)

func (r *Reader) ReadAll() (records [][]string, err error)

ReadAll 从 r 读取所有剩余的记录。每条记录都是一片田地。成功的调用返回 err == nil,而不是 err == io.EOF。由于 ReadAll 被定义为读取直到 EOF,因此它不会将文件末尾视为要报告的错误。

示例

package main

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

func main() {
	in := `first_name,last_name,username
"Rob","Pike",rob
Ken,Thompson,ken
"Robert","Griesemer","gri"
`
	r := csv.NewReader(strings.NewReader(in))

	records, err := r.ReadAll()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(records)
}

Writer 将记录写入 CSV 编码文件。

如 NewWriter 返回的,Writer 写入由换行符终止的记录,并使用 ',' 作为字段分隔符。在首次调用 Write 或 WriteAll 之前,可以更改导出的字段以定制细节。

逗号是字段分隔符。

如果 UseCRLF 为 true,则 Writer 以 \r\n 结束每个记录而不是 \n。

type Writer struct {
        Comma   rune // 字段分隔符(由NewWriter设置为','
        UseCRLF bool // 如果使用 \r\n 作为行终止符,则为True
        // 包含已过滤或未导出的字段
}

示例

package main

import (
	"encoding/csv"
	"log"
	"os"
)

func main() {
	records := [][]string{
		{"first_name", "last_name", "username"},
		{"Rob", "Pike", "rob"},
		{"Ken", "Thompson", "ken"},
		{"Robert", "Griesemer", "gri"},
	}

	w := csv.NewWriter(os.Stdout)

	for _, record := range records {
		if err := w.Write(record); err != nil {
			log.Fatalln("error writing record to csv:", err)
		}
	}

	// Write any buffered data to the underlying writer (standard output).
	w.Flush()

	if err := w.Error(); err != nil {
		log.Fatal(err)
	}
}

func NewWriter(查看源代码)

func NewWriter(w io.Writer) *Writer

NewWriter 返回一个写入 w 的新 Writer。

func (*Writer) Error(查看源代码)

func (w *Writer) Error() error

错误报告在先前写入或刷新期间发生的任何错误。

func (*Writer) Flush(查看源代码)

func (w *Writer) Flush()

Flush 将任何缓冲的数据写入底层的 io.Writer。要检查在刷新过程中是否发生错误,请调用错误。

func (*Writer) Write(查看源代码)

func (w *Writer) Write(record []string) error

Writer 写一个 CSV 记录以及任何必要的报价。记录是一串字符串,每个字符串都是一个字段。

func (*Writer) WriteAll(查看源代码)

func (w *Writer) WriteAll(records [][]string) error

WriteAll 使用 Write 写入多个 CSV 记录,然后调用 Flush。

示例

package main

import (
	"encoding/csv"
	"log"
	"os"
)

func main() {
	records := [][]string{
		{"first_name", "last_name", "username"},
		{"Rob", "Pike", "rob"},
		{"Ken", "Thompson", "ken"},
		{"Robert", "Griesemer", "gri"},
	}

	w := csv.NewWriter(os.Stdout)
	w.WriteAll(records) // calls Flush internally

	if err := w.Error(); err != nil {
		log.Fatalln("error writing csv:", err)
	}
}

扫码关注腾讯云开发者

领取腾讯云代金券