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

时间:2016-06-05 19:24:23

标签: 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]))
    }
}

我要找的结果是:

1)teststring
2)teststring
3)teststring
4)teststring
5)teststring

如何使用time.Sleep(1 * time.Second)来模拟延迟?

1 个答案:

答案 0 :(得分:3)

您确定要使用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]))
    }
}