Home > Backend Development > Golang > How to Read a File Starting from a Specific Line Number in Go using a Scanner?

How to Read a File Starting from a Specific Line Number in Go using a Scanner?

Barbara Streisand
Release: 2024-11-08 10:01:02
Original
502 people have browsed it

How to Read a File Starting from a Specific Line Number in Go using a Scanner?

How to Read a File Starting from a Specific Line Number Using Scanner?

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:

1. Extending Scanner with a Split Function

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()
}
Copy after login

2. Using bufio.Reader

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
}
Copy after login

Testing the Solutions

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
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template