dqnf28092 2015-06-18 08:43
浏览 59

为什么io.reader在读取后变为空?

func foo(buf *bytes.Buffer) {
    fmt.Println("0: ", len(buf.Bytes()))
    ioutil.ReadAll(buf)
    fmt.Println("1: ", len(buf.Bytes()))
}

The code shows the correct length the first time, but the second times it shows the length is zero.

  • 写回答

1条回答 默认 最新

  • drhwb470572 2015-06-18 08:52
    关注

    Reading from a bytes.Buffer drains or consumes the bytes that were read. This means if you try to read again, those will not be returned.

    Buffer.Bytes() returns the unread portion of the buffer, so it is the expected result for you to see 0 length after everything has been read (this is exactly what ioutil.ReadAll() does).


    What if you just want to "peek" and not really "read" bytes?

    There is no "peek" functionality in bytes.Buffer. The easiest would be to get the bytes of the buffer, and construct another bytes.Buffer from it and read from the new buffer.

    It could look something like this:

    func peek(buf *bytes.Buffer, b []byte) (int, error) {
        buf2 := bytes.NewBuffer(buf.Bytes())
        return buf2.Read(b)
    }
    

    peek() in action:

    Error checks omitted for simplicity:

    buf := &bytes.Buffer{}
    
    buf.WriteString("Hello")
    fmt.Printf("Len: %d, Content: %s
    ", buf.Len(), buf)
    
    fmt.Println("
    Peeking...")
    data := make([]byte, 4)
    peek(buf, data)
    fmt.Printf("Peeked: %s
    ", data)
    fmt.Printf("Len: %d, Content: %s
    ", buf.Len(), buf)
    
    fmt.Println("
    Reading...")
    data = make([]byte, buf.Len())
    buf.Read(data)
    fmt.Printf("Read: %s
    ", data)
    fmt.Printf("Len: %d, Content: %s
    ", buf.Len(), buf)
    

    Output (try it on the Go Playground):

    Len: 5, Content: Hello
    
    Peeking...
    Peeked: Hell
    Len: 5, Content: Hello
    
    Reading...
    Read: Hello
    Len: 0, Content: 
    
    评论

报告相同问题?