前言
CSV是以逗号为分隔符分割字段,一个csv文件包含零到多条记录,每条记录一到多个字段。每个记录用换行符分隔。
在我们的业务中可能会遇到解析CSV文件的功能,而Go的标准库中也提供了对CSV文件的读写操作。
Reader
type Reader struct {
Comma rune
Comment rune
FieldsPerRecord int
LazyQuotes bool
TrailingComma bool
TrimLeadingSpace bool
// 内含隐藏或非导出字段
}
Comma: 字段分隔符。使用NewReader初始化的Reader对象默认分隔符为逗号。
Comment: 一行开始位置的注释标识符。Comment如果不是0,则表示以Comment声明的注释标识符开始的行会被忽略。
FieldsPerRecord:每条记录期望的字段数。
- 大于0:当每行的字段超过该值,报错
- 等于0:这是默认值。检查第一行的字段数量,然后赋值给 FieldsPerRecord
- 小于0:不检查
LazyQuotes:是否允许懒引号。
TrimLeadingSpace:去除首部的空白符。
// NewReader returns a new Reader that reads from r.
func NewReader(r io.Reader) *Reader {
return &Reader{
Comma: ',',
r: bufio.NewReader(r),
}
}
初始化方法的参数为io.Reader类型的接口。如果是从文件读取,可以直接传入os.File。除此之外还可以是各种类型的Reader或者Buffer。
func (r *Reader) Read() (record []string, err error)
func (r *Reader) ReadAll() (records [][]string, err error)
- Read方法一次读取一行数据,按分隔符将字段分割后,以字符串切片形式返回。
- ReadAll方法读取CSV的所有内容到内存,返回以每条记录为内容的二维切片。
Writer
type Writer struct {
Comma rune
UseCRLF bool
// 内含隐藏或非导出字段
}
Comma:同Reader
UseCRLF: true时记录之间使用\r\n分割
// NewWriter returns a new Writer that writes to w.
func NewWriter(w io.Writer) *Writer {
return &Writer{
Comma: ',',
w: bufio.NewWriter(w),
}
}
初始化方法和Reader相似,不再展开。
func (w *Writer) Write(record []string) (err error)
func (w *Writer) WriteAll(records [][]string) (err error)
Write和WriteAll与Reader类似,不再展开。
Example
readCSR := func() error {
file, err := os.Open("test.csv")
defer file.Close()
if err != nil {
return errors.New(fmt.Sprintf("error to open file: %s", err))
}
//case1: 按行读
reader := csv.NewReader(file)
for {
line, err := reader.Read()
if err == io.EOF {
fmt.Println("all done")
break
}
if err != nil {
return errors.New(fmt.Sprintf("error to read file: %s", err))
}
fmt.Println("content is: ", line)
}
//case2: 读全部
all, err := reader.ReadAll()
if err != nil {
return errors.New(fmt.Sprintf("error to read file: %s", err))
}
for idx, line := range all {
fmt.Println("the ", idx, " line's content is: ", line)
}
}