gpt4 book ai didi

go - 长时间运行复制到 bytes.Buffer

转载 作者:IT王子 更新时间:2023-10-29 02:12:47 25 4
gpt4 key购买 nike

我有一个长寿的 io.Reader,它每隔几秒返回一些数据(从不返回 EOF),还有一个 goroutine,它从该阅读器执行 io.Copy 到一个 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.Buffer(io.Copy 并定期读取)吗?

最佳答案

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

如果您使用 FIFO (io.Pipe) 来同步读取和写入,则不需要任何额外的锁或 channel 来跟踪第一个 io.Reader .这是一个示例 read 函数,它在缓冲区已满时打印,或者在上次打印语句后等待一段时间:

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

关于go - 长时间运行复制到 bytes.Buffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40834275/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com