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 }