我试图在Go中编写一个函数来生成XML并为它返回一个阅读器。但是,XML编码器似乎需要编写器才能写入,并且我不太确定如何将编写器的输出传递给我想要返回的读者。
我试过了:
func (i *Item) ToRss() io.Reader {
reader, writer := io.Pipe()
enc := xml.NewEncoder(writer)
enc.Indent(" ", " ")
enc.Encode(i)
return reader
}
但是当我运行以下内容时,我会收到一个致命的错误:
r := a.ToRss()
buf := new(bytes.Buffer)
buf.ReadFrom(r)
s := buf.String()
fmt.Println(s)
致命错误:所有goroutine都睡着了 - 死锁!
最后,我想将读者管道输出到HTTP请求的输出。我应该只返回一个[]字节吗?或者有一种缓冲输出的好方法,以便客户端可以使用阅读器吗?
谢谢!
答案 0 :(得分:2)
管道没有内部缓冲。它会在读或写时阻塞,直到调用相应的写或读。
您应该在ToRss中使用bytes.Buffer并将其作为读者返回:
func ToRss() io.Reader {
buf := &bytes.Buffer{}
io.WriteString(buf, "foo")
return buf
}
或者,您可以启动一个新的goroutine来写入管道并将其返回以从主goroutine上读取。这种方法可以避免不必要的缓冲,但会引入另一种goroutine。
func ToRss() io.Reader {
reader, writer := io.Pipe()
go func() {
io.WriteString(writer, "foo")
writer.Close()
}()
return reader
}