Documentation ¶
Overview ¶
Package yacr is yet another CSV reader (and writer) with small memory usage.
Example ¶
package main import ( "fmt" "os" yacr "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) } }
Output:
Example (Reader) ¶
package main import ( "fmt" "strings" yacr "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" yacr "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" yacr "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" yacr "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.