github.com/shuguocloud/go-zero@v1.3.0/core/iox/read.go (about)

     1  package iox
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"strings"
    10  )
    11  
    12  type (
    13  	textReadOptions struct {
    14  		keepSpace     bool
    15  		withoutBlanks bool
    16  		omitPrefix    string
    17  	}
    18  
    19  	// TextReadOption defines the method to customize the text reading functions.
    20  	TextReadOption func(*textReadOptions)
    21  )
    22  
    23  // DupReadCloser returns two io.ReadCloser that read from the first will be written to the second.
    24  // The first returned reader needs to be read first, because the content
    25  // read from it will be written to the underlying buffer of the second reader.
    26  func DupReadCloser(reader io.ReadCloser) (io.ReadCloser, io.ReadCloser) {
    27  	var buf bytes.Buffer
    28  	tee := io.TeeReader(reader, &buf)
    29  	return ioutil.NopCloser(tee), ioutil.NopCloser(&buf)
    30  }
    31  
    32  // KeepSpace customizes the reading functions to keep leading and tailing spaces.
    33  func KeepSpace() TextReadOption {
    34  	return func(o *textReadOptions) {
    35  		o.keepSpace = true
    36  	}
    37  }
    38  
    39  // ReadBytes reads exactly the bytes with the length of len(buf)
    40  func ReadBytes(reader io.Reader, buf []byte) error {
    41  	var got int
    42  
    43  	for got < len(buf) {
    44  		n, err := reader.Read(buf[got:])
    45  		if err != nil {
    46  			return err
    47  		}
    48  
    49  		got += n
    50  	}
    51  
    52  	return nil
    53  }
    54  
    55  // ReadText reads content from the given file with leading and tailing spaces trimmed.
    56  func ReadText(filename string) (string, error) {
    57  	content, err := ioutil.ReadFile(filename)
    58  	if err != nil {
    59  		return "", err
    60  	}
    61  
    62  	return strings.TrimSpace(string(content)), nil
    63  }
    64  
    65  // ReadTextLines reads the text lines from given file.
    66  func ReadTextLines(filename string, opts ...TextReadOption) ([]string, error) {
    67  	var readOpts textReadOptions
    68  	for _, opt := range opts {
    69  		opt(&readOpts)
    70  	}
    71  
    72  	file, err := os.Open(filename)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	defer file.Close()
    77  
    78  	var lines []string
    79  	scanner := bufio.NewScanner(file)
    80  	for scanner.Scan() {
    81  		line := scanner.Text()
    82  		if !readOpts.keepSpace {
    83  			line = strings.TrimSpace(line)
    84  		}
    85  		if readOpts.withoutBlanks && len(line) == 0 {
    86  			continue
    87  		}
    88  		if len(readOpts.omitPrefix) > 0 && strings.HasPrefix(line, readOpts.omitPrefix) {
    89  			continue
    90  		}
    91  
    92  		lines = append(lines, line)
    93  	}
    94  
    95  	return lines, scanner.Err()
    96  }
    97  
    98  // WithoutBlank customizes the reading functions to ignore blank lines.
    99  func WithoutBlank() TextReadOption {
   100  	return func(o *textReadOptions) {
   101  		o.withoutBlanks = true
   102  	}
   103  }
   104  
   105  // OmitWithPrefix customizes the reading functions to ignore the lines with given leading prefix.
   106  func OmitWithPrefix(prefix string) TextReadOption {
   107  	return func(o *textReadOptions) {
   108  		o.omitPrefix = prefix
   109  	}
   110  }