encoding/csv
Package 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
type Reader(查看源代码)
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)
}
type Writer(查看源代码)
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)
}
}