bufio.NewScanner(r)从r调用Scan()排放缓冲区

I want to create 2 scanners from the same reader r. But when calling Scan() from the first scanner, it drains the buffer from r, so the second scanner is reading a zero buffer. Is that a common behavior? How to fix it so that the second scanner properly reads from the original r?

r := bytes.NewReader([]byte("ninebytes"))
fmt.Println(r.Len()) // 9
sc1 := bufio.NewScanner(r)
sc1.Scan()
fmt.Printf("scanner1: %s
", sc1.Text()) // scanner1: ninebytes

// i want create new scanner from r too
fmt.Println(r.Len()) // 0
sc2 := bufio.NewScanner(r)
sc1.Scan()
fmt.Printf("scanner2: %s
", sc2.Text()) // scanner2: 

Here's an example at play golang

This is what I'm trying to do: read a specific line from a file, but when calling the function a second time, r is drained.

func readLineScanner(r io.Reader, lineNum int) ([]byte, error) {
    sc := bufio.NewScanner(r)
    lastLine := 0
    for sc.Scan() {
        lastLine++
        if lastLine == lineNum {
            break
        }
    }
    return sc.Bytes(), sc.Err()
}

Reading a reader is in general a destructive action; particularly with http request bodies.

Instead you can create a tee reader, which is modelled on the unix tee command.

Link to the docs

Modifying the example you've given:

r := bytes.NewReader([]byte("ninebytes"))

var buf bytes.Buffer
tee := io.TeeReader(r, &buf)

sc1 := bufio.NewScanner(tee)
sc1.Scan()
fmt.Printf("scanner1: %s
", sc1.Text())

sc2 := bufio.NewScanner(&buf)
sc2.Scan()
fmt.Printf("scanner2: %s
", sc2.Text())

Using a tee reader, as you read from r it will write a copy of those bytes to buf, which you can use again in the second scanner.