如何处理 bytes.Buffer 流中的 io.EOF?

Ger*_*ens 4 go

https://play.golang.org/p/JKXKa7Pvjd

我想弄清楚如何使用 bytes.Buffer 测试我的后台函数,其中流中可以有随机 io.EOF?

例子:

package main

import (
    "fmt"
    "io"
    "bytes"
    "time"
)

func main() {
    buffer := new(bytes.Buffer)
    go background(buffer)
    i := 0
    for i < 5 {
        i++
        fmt.Fprintf(buffer, "%d)teststring\n", i)
        time.Sleep(1 * time.Second) // generates a io.EOF

    }
    time.Sleep(1 * time.Second)
}

func background(r io.Reader) {
    buf := make([]byte, 64)
    for {   
        n, err := r.Read(buf)
        if err != nil {
            fmt.Print(err.Error())
            return // removing `return` will result in race condition
        }
        fmt.Print(string(buf[:n]))
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找的结果是:

1)teststring
2)teststring
3)teststring
4)teststring
5)teststring
Run Code Online (Sandbox Code Playgroud)

如何使用time.Sleep(1 * time.Second)模拟延迟来实现这一点?

Dar*_*aaz 7

您确定要使用 bytes.Buffer 吗?它不是流,也不是线程安全的,这就是为什么你会遇到竞争条件。使用io.Pipe()

https://play.golang.org/p/c0fLEI350w

package main

import (
    "fmt"
    "io"
    "time"
)

func main() {
    pr, pw := io.Pipe()
    go background(pr)
    i := 0
    for i < 5 {
        i++
        fmt.Fprintf(pw, "%d)teststring\n", i)
        time.Sleep(1 * time.Second)

    }
    time.Sleep(1 * time.Second)
}

func background(r io.Reader) {
    buf := make([]byte, 64)
    for {
        n, err := r.Read(buf)
        if err != nil {
            fmt.Print(err.Error())
            //return
        }
        fmt.Print(string(buf[:n]))
    }
}
Run Code Online (Sandbox Code Playgroud)