textfile.go 594 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. package iox
  2. import (
  3. "bytes"
  4. "errors"
  5. "io"
  6. "os"
  7. )
  8. const bufSize = 32 * 1024
  9. // CountLines returns the number of lines in file.
  10. func CountLines(file string) (int, error) {
  11. f, err := os.Open(file)
  12. if err != nil {
  13. return 0, err
  14. }
  15. defer f.Close()
  16. var noEol bool
  17. buf := make([]byte, bufSize)
  18. count := 0
  19. lineSep := []byte{'\n'}
  20. for {
  21. c, err := f.Read(buf)
  22. count += bytes.Count(buf[:c], lineSep)
  23. switch {
  24. case errors.Is(err, io.EOF):
  25. if noEol {
  26. count++
  27. }
  28. return count, nil
  29. case err != nil:
  30. return count, err
  31. }
  32. noEol = c > 0 && buf[c-1] != '\n'
  33. }
  34. }