123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- package iox
- import (
- "bufio"
- "bytes"
- "io"
- "io/ioutil"
- "os"
- "strings"
- )
- type (
- textReadOptions struct {
- keepSpace bool
- withoutBlanks bool
- omitPrefix string
- }
- // TextReadOption defines the method to customize the text reading functions.
- TextReadOption func(*textReadOptions)
- )
- // DupReadCloser returns two io.ReadCloser that read from the first will be written to the second.
- // The first returned reader needs to be read first, because the content
- // read from it will be written to the underlying buffer of the second reader.
- func DupReadCloser(reader io.ReadCloser) (io.ReadCloser, io.ReadCloser) {
- var buf bytes.Buffer
- tee := io.TeeReader(reader, &buf)
- return ioutil.NopCloser(tee), ioutil.NopCloser(&buf)
- }
- // KeepSpace customizes the reading functions to keep leading and tailing spaces.
- func KeepSpace() TextReadOption {
- return func(o *textReadOptions) {
- o.keepSpace = true
- }
- }
- // ReadBytes reads exactly the bytes with the length of len(buf)
- func ReadBytes(reader io.Reader, buf []byte) error {
- var got int
- for got < len(buf) {
- n, err := reader.Read(buf[got:])
- if err != nil {
- return err
- }
- got += n
- }
- return nil
- }
- // ReadText reads content from the given file with leading and tailing spaces trimmed.
- func ReadText(filename string) (string, error) {
- content, err := ioutil.ReadFile(filename)
- if err != nil {
- return "", err
- }
- return strings.TrimSpace(string(content)), nil
- }
- // ReadTextLines reads the text lines from given file.
- func ReadTextLines(filename string, opts ...TextReadOption) ([]string, error) {
- var readOpts textReadOptions
- for _, opt := range opts {
- opt(&readOpts)
- }
- file, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- var lines []string
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- line := scanner.Text()
- if !readOpts.keepSpace {
- line = strings.TrimSpace(line)
- }
- if readOpts.withoutBlanks && len(line) == 0 {
- continue
- }
- if len(readOpts.omitPrefix) > 0 && strings.HasPrefix(line, readOpts.omitPrefix) {
- continue
- }
- lines = append(lines, line)
- }
- return lines, scanner.Err()
- }
- // WithoutBlank customizes the reading functions to ignore blank lines.
- func WithoutBlank() TextReadOption {
- return func(o *textReadOptions) {
- o.withoutBlanks = true
- }
- }
- // OmitWithPrefix customizes the reading functions to ignore the lines with given leading prefix.
- func OmitWithPrefix(prefix string) TextReadOption {
- return func(o *textReadOptions) {
- o.omitPrefix = prefix
- }
- }
|