Initially, you may encounter challenges in reading a file line by line and saving the progress in Go. Scanner from the bufio package doesn't provide methods for line numbers. However, here are potential solutions:
bufio.Scanner can be extended to maintain positions. Implement a split function that splits the input into tokens (lines) and track the read bytes. The example below uses the builtin bufio.ScanLines() as a base and maintains the position (pos) using the advance return value:
func withScanner(input io.ReadSeeker, start int64) error { if _, err := input.Seek(start, 0); err != nil { return err } scanner := bufio.NewScanner(input) pos := start scanLines := func(data []byte, atEOF bool) (advance int, token []byte, err error) { advance, token, err = bufio.ScanLines(data, atEOF) pos += int64(advance) return } scanner.Split(scanLines) for scanner.Scan() { fmt.Printf("Pos: %d, Scanned: %s\n", pos, scanner.Text()) } return scanner.Err() }
bufio.Reader allows you to read a line with ReadBytes() using 'n' as the delimeter. The example below handles multiple line terminator sequences (rn) and strips them from the read line:
func withReader(input io.ReadSeeker, start int64) error { if _, err := input.Seek(start, 0); err != nil { return err } r := bufio.NewReader(input) pos := start for { data, err := r.ReadBytes('\n') pos += int64(len(data)) if err == nil || err == io.EOF { if len(data) > 0 && data[len(data)-1] == '\n' { data = data[:len(data)-1] } if len(data) > 0 && data[len(data)-1] == '\r' { data = data[:len(data)-1] } fmt.Printf("Pos: %d, Read: %s\n", pos, data) } if err != nil { if err != io.EOF { return err } break } } return nil }
To test the solutions, you can use the content "firstrnsecondnthirdnfourth" as input with both a clean start (start = 0) and a resume position (start = 14). The output will display the positions and read lines:
--SCANNER, start: 0 Pos: 7, Scanned: first Pos: 14, Scanned: second Pos: 20, Scanned: third Pos: 26, Scanned: fourth --READER, start: 0 Pos: 7, Read: first Pos: 14, Read: second Pos: 20, Read: third Pos: 26, Read: fourth --SCANNER, start: 14 Pos: 20, Scanned: third Pos: 26, Scanned: fourth --READER, start: 14 Pos: 20, Read: third Pos: 26, Read: fourth
The above is the detailed content of How to Read a File Starting from a Specific Line Number in Go using a Scanner?. For more information, please follow other related articles on the PHP Chinese website!