go - 在 Go 中将一个 writer 包装在一个 reader 中?

标签 go

我正在尝试用 Go 编写一个函数,它生成 XML 并为其返回一个读取器。但是,XML 编码器似乎需要一个写入器来写入,我不太确定如何将写入器的输出通过管道传输到我想要返回的读取器。

我试过这个:

func (i *Item) ToRss() io.Reader {                                                     
  reader, writer := io.Pipe()                                                             
  enc := xml.NewEncoder(writer)                                                           
  enc.Indent("  ", "   ")                                                                 
  enc.Encode(i)                                                                           
  return reader                                                                           
}

但是当我运行下面的命令时,我得到了一个 fatal error :

  r := a.ToRss()
  buf := new(bytes.Buffer)
  buf.ReadFrom(r)
  s := buf.String()
  fmt.Println(s)

fatal error: all goroutines are asleep - deadlock!

最后,我想将读者引导至 HTTP 请求的输出。我应该只返回一个 []byte 吗?或者是否有缓冲输出以便客户端可以使用阅读器的好方法?

最佳答案

管道没有内部缓冲。它会阻塞读取或写入,直到调用相应的写入或读取。

您应该在 ToRss 中使用 bytes.Buffer 并将其作为您的阅读器返回:

func ToRss() io.Reader {
    buf := &bytes.Buffer{}
    io.WriteString(buf, "foo")
    return buf
} 

Playground link

或者,您可以启动一个新的 goroutine 来写入管道并将其返回以在主 goroutine 上读取。此方法将避免不必要的缓冲,但会引入另一个 goroutine。

func ToRss() io.Reader {
   reader, writer := io.Pipe()
   go func() {
      io.WriteString(writer, "foo")
      writer.Close()
   }()
   return reader
}

Playground Link

关于go - 在 Go 中将一个 writer 包装在一个 reader 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29711898/

相关文章:

go - binary.Write() 字节排序不适用于 []byte

go - golang中的等效盐和哈希

arrays - 在 Go 中,如何将 [16]float32 转换为 *float32

parameters - Go 如何查看产品类型

xml - 如何使用 Golang 解码 Reddit 的 RSS?

scala - scala/akka 或 go 更适合的问题

algorithm - 递归旅行推销员喜欢在 go 中计算

linux - 起订量 : running "moq": exec: "moq": executable file not found in $PATH

go - 计算预定义数字类型之外的大数

go - GRPC-GO:生成的 pb.go 文件中未显示客户端 stub