You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

io.go 1.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package common
  2. import (
  3. "bufio"
  4. "os"
  5. "unicode"
  6. "unicode/utf8"
  7. )
  8. // ReadFileAsInts reads all lines from the given path and returns them in a slice of ints.
  9. // If an error occurs, the function will panic.
  10. func ReadFileAsInts(path string) []int {
  11. return readIntsWithScanner(path, bufio.ScanLines)
  12. }
  13. // ReadCsvAsInts reads all data from the given path and returns an int slice
  14. // containing comma-delimited parts. If an error occurs, the function will panic.
  15. func ReadCsvAsInts(path string) []int {
  16. return readIntsWithScanner(path, scanByCommas)
  17. }
  18. func readIntsWithScanner(path string, splitFunc bufio.SplitFunc) []int {
  19. file, err := os.Open(path)
  20. if err != nil {
  21. panic(err)
  22. }
  23. defer func() {
  24. _ = file.Close()
  25. }()
  26. var parts []int
  27. scanner := bufio.NewScanner(file)
  28. scanner.Split(splitFunc)
  29. for scanner.Scan() {
  30. parts = append(parts, MustAtoi(scanner.Text()))
  31. }
  32. if scanner.Err() != nil {
  33. panic(scanner.Err())
  34. }
  35. return parts
  36. }
  37. // scanByCommas is a split function for a Scanner that returns each
  38. // comma-separated section of text, with surrounding spaces deleted.
  39. // The definition of space is set by unicode.IsSpace.
  40. func scanByCommas(data []byte, atEOF bool) (advance int, token []byte, err error) {
  41. // Skip leading spaces.
  42. start := 0
  43. for width := 0; start < len(data); start += width {
  44. var r rune
  45. r, width = utf8.DecodeRune(data[start:])
  46. if !unicode.IsSpace(r) {
  47. break
  48. }
  49. }
  50. // Scan until comma, marking end of word.
  51. for width, i := 0, start; i < len(data); i += width {
  52. var r rune
  53. r, width = utf8.DecodeRune(data[i:])
  54. if r == ',' || unicode.IsSpace(r) {
  55. return i + width, data[start:i], nil
  56. }
  57. }
  58. // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
  59. if atEOF && len(data) > start {
  60. return len(data), data[start:], nil
  61. }
  62. // Request more data.
  63. return start, nil, nil
  64. }