长期运行的副本bytes.Buffer

我有一个长期生活io.Reader返回每隔几秒钟(从来没有EOF)的一些数据,并做了io.Copy从读者到bytes.Buffer一个够程(也永远不会终止)。像这样的东西:长期运行的副本bytes.Buffer

var src io.Reader 

var buf bytes.Buffer

func main() {

go io.Copy(&buf, src)

// Do stuff. Read from the buffer periodically.

}

我不明白的是,我看到奇怪的结果,当我试图从该缓冲区读取。无论我是否拨打buf.Bytes()ioutil.ReadAll(&buf)或任何其他内容,我只会看到第一个字节反复写入缓冲区。

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

我的问题是,我究竟做错了什么?我可以以这种方式使用bytes.Bufferio.Copy并定期阅读)吗?

回答:

您无法将您的读取调用与bytes.Buffer中发生的写入同步到io.Copy中。即使您将bytes.Buffer包装在结构中以锁定读/写方法,当Copy等待写入时ReadAll在Read上被阻塞时,您也会发生死锁。您需要手动执行复制,并正确序列化所有访问,或将读写分隔为io.Pipe

如果您使用FIFO(io.Pipe)来同步读取和写入,则不需要任何额外的锁定或通道来追踪第一个io.Reader。这里有一个例子read功能,要么打印时它的缓冲区已满,或等待自上次print语句一些间隔:

func read(r io.Reader) { 

buf := make([]byte, 1024)

pos := 0

lastPrint := time.Now()

for {

n, err := r.Read(buf[pos:])

if n > 0 {

pos += n

}

if pos >= len(buf) || time.Since(lastPrint) > 125*time.Millisecond && pos > 0 {

fmt.Println("read:", buf[:pos])

lastPrint = time.Now()

pos = 0

}

if err != nil {

fmt.Println(err)

break

}

}

if pos > 0 {

fmt.Println("read:", buf[:pos])

}

}

func main() {

pr, pw := io.Pipe()

go func() {

io.Copy(pw, &trickle{})

pw.Close()

}()

read(pr)

}

https://play.golang.org/p/8NeV3v0LOU

以上是 长期运行的副本bytes.Buffer 的全部内容, 来源链接: utcz.com/qa/261579.html

回到顶部