github.com/lingyao2333/mo-zero@v1.4.1/core/iox/read.go (about)

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