Documentation
¶
Overview ¶
Package yacr is yet another CSV reader (and writer) with small memory usage.
Example ¶
package main
import (
"fmt"
"os"
"github.com/gwenn/yacr"
)
func main() {
r := yacr.NewReader(os.Stdin, '\t', false, false)
w := yacr.NewWriter(os.Stdout, '\t', false)
for r.Scan() && w.Write(r.Bytes()) {
if r.EndOfRecord() {
w.EndOfRecord()
}
}
w.Flush()
if err := r.Err(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
}
if err := w.Err(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
}
}
Example (Reader) ¶
package main
import (
"fmt"
"strings"
"github.com/gwenn/yacr"
)
func main() {
r := yacr.DefaultReader(strings.NewReader("c1,\"c\"\"2\",\"c\n3\",\"c,4\""))
fmt.Print("[")
for r.Scan() {
fmt.Print(r.Text())
if r.EndOfRecord() {
fmt.Print("]\n")
} else {
fmt.Print(" ")
}
}
if err := r.Err(); err != nil {
fmt.Println(err)
}
}
Output: [c1 c"2 c 3 c,4]
Example (Writer) ¶
package main
import (
"fmt"
"os"
"github.com/gwenn/yacr"
)
func main() {
w := yacr.DefaultWriter(os.Stdout)
for _, field := range []string{"c1", "c\"2", "c\n3", "c,4"} {
if !w.WriteString(field) {
break
}
}
w.Flush()
if err := w.Err(); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
}
}
Output: c1,"c""2","c 3","c,4"
Index ¶
- Variables
- func IsNumber(s []byte) (isNum bool, isReal bool)
- func Zopen(filepath string) (io.ReadCloser, error)
- type Reader
- func (s *Reader) EndOfRecord() bool
- func (s *Reader) IsNumber() (isNum bool, isReal bool)
- func (s *Reader) LineNumber() int
- func (s *Reader) ScanField(data []byte, atEOF bool) (advance int, token []byte, err error)
- func (s *Reader) ScanHeaders() error
- func (s *Reader) ScanRecord(values ...interface{}) (int, error)
- func (s *Reader) ScanRecordByName(args ...interface{}) (int, error)
- func (s *Reader) ScanValue(value interface{}) error
- func (s *Reader) Sep() byte
- func (s *Reader) SkipRecords(n int) error
- func (s *Reader) Value(value interface{}) error
- type Writer
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNewLine is the error returned when a value contains a newline in unquoted mode. ErrNewLine = errors.New("yacr.Writer: newline character in value") // ErrSeparator is the error returned when a value contains a separator in unquoted mode. ErrSeparator = errors.New("yacr.Writer: separator in value") )
Functions ¶
Types ¶
type Reader ¶
type Reader struct {
*bufio.Scanner
Trim bool // trim spaces (only on unquoted values). Break rfc4180 rule: "Spaces are considered part of a field and should not be ignored."
Comment byte // character marking the start of a line comment. When specified (not 0), line comment appears as empty line.
Lazy bool // specify if quoted values may contains unescaped quote not followed by a separator or a newline
Headers map[string]int // Index (first is 1) by header
// contains filtered or unexported fields
}
Reader provides an interface for reading CSV data (compatible with rfc4180 and extended with the option of having a separator other than ","). Successive calls to the Scan method will step through the 'fields', skipping the separator/newline between the fields. The EndOfRecord method tells when a field is terminated by a line break.
func DefaultReader ¶
DefaultReader creates a "standard" CSV reader (separator is comma and quoted mode active)
func NewReader ¶
NewReader returns a new CSV scanner to read from r. When quoted is false, values must not contain a separator or newline.
func (*Reader) EndOfRecord ¶
EndOfRecord returns true when the most recent field has been terminated by a newline (not a separator).
func (*Reader) IsNumber ¶
IsNumber determines if the current token is a number or not. Only works for single-byte encodings (ASCII, ISO-8859-1) and UTF-8.
func (*Reader) LineNumber ¶
LineNumber returns current line number (not record number)
func (*Reader) ScanField ¶
ScanField implements bufio.SplitFunc for CSV. Lexing is adapted from csv_read_one_field function in SQLite3 shell sources.
func (*Reader) ScanHeaders ¶
ScanHeaders loads current line as the header line.
func (*Reader) ScanRecord ¶
ScanRecord decodes one line fields to values. Empty lines are ignored/skipped. It's like fmt.Scan or database.sql.Rows.Scan. Returns (0, nil) on EOF, (*, err) on error and (n >= 1, nil) on success (n may be less or greater than len(values)).
var n int
var err error
for {
values := make([]string, N)
if n, err = s.ScanRecord(&values[0]/*, &values[1], ...*/); err != nil || n == 0 {
break // or error handling
} else if (n > N) {
n = N // ignore extra values
}
for _, value := range values[0:n] {
// ...
}
}
if err != nil {
// error handling
}
Example ¶
package main
import (
"fmt"
"strings"
"github.com/gwenn/yacr"
)
func main() {
r := yacr.DefaultReader(strings.NewReader("11,12,13,14\n21,22,23,24\n31,32,33,34\n41,42,43,44"))
fmt.Print("[")
var i1, i2, i3, i4 int
for {
if n, err := r.ScanRecord(&i1, &i2, &i3, &i4); err != nil {
fmt.Println(err)
break
} else if n != 4 {
break
}
fmt.Println(i1, i2, i3, i4)
}
fmt.Print("]")
}
Output: [11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 ]
func (*Reader) ScanRecordByName ¶
ScanRecordByName decodes one line fields by name (name1, value1, ...). Specified names must match Headers.
func (*Reader) ScanValue ¶
ScanValue advances to the next token and decodes field's content to value. The value may point to data that will be overwritten by a subsequent call to Scan.
func (*Reader) SkipRecords ¶
SkipRecords skips n records/headers
func (*Reader) Value ¶
Value decodes field's content to value. The value may point to data that will be overwritten by a subsequent call to Scan.
Example ¶
package main
import (
"fmt"
"strings"
"github.com/gwenn/yacr"
)
func main() {
r := yacr.DefaultReader(strings.NewReader("1,\"2\",3,4"))
fmt.Print("[")
var i int
for r.Scan() {
if err := r.Value(&i); err != nil {
fmt.Println(err)
break
}
fmt.Print(i)
if r.EndOfRecord() {
fmt.Print("]\n")
} else {
fmt.Print(" ")
}
}
if err := r.Err(); err != nil {
fmt.Println(err)
}
}
Output: [1 2 3 4]
type Writer ¶
type Writer struct {
UseCRLF bool // True to use \r\n as the line terminator
// contains filtered or unexported fields
}
Writer provides an interface for writing CSV data (compatible with rfc4180 and extended with the option of having a separator other than ","). Successive calls to the Write method will automatically insert the separator. The EndOfRecord method tells when a line break is inserted.
func DefaultWriter ¶
DefaultWriter creates a "standard" CSV writer (separator is comma and quoted mode active)
func (*Writer) EndOfRecord ¶
func (w *Writer) EndOfRecord()
EndOfRecord tells when a line break must be inserted.
func (*Writer) WriteRecord ¶
WriteRecord ensures that values are quoted when needed. It's like fmt.Println.
func (*Writer) WriteString ¶
WriteString ensures that value is quoted when needed.
func (*Writer) WriteValue ¶
WriteValue ensures that value is quoted when needed. Value's type/kind is used to encode value to text.