自定义读取器,直到遇到标记为止。

huangapple go评论93阅读模式
英文:

Custom reader until mark is encountered

问题

在阅读了很多关于Go语言中读写器的内容后,我对如何实现一个自定义的io.ReadWriter,它会一直读取(并阻塞)直到被标记为完成感到有些困惑。一个示例实现如下:

var rw io.ReadWriter // 我的自定义ReadWriter

// 以非阻塞的方式向其中写入数据:
go func() {
    fmt.Fprintf(rw, "Line one\n")
    // ...更多写入操作
    fmt.Fprintf(rw, "END") // 如何最好地标记写入器已完成???
}()

// 从中读取数据,并在**遇到结束标记**之前阻塞
_, _ = io.Copy(dst, rw)

一些相关的问题:

  • http.Response.Body 如何标记响应体已完成,以便 io.Copy() 知道何时停止读取?
  • 如何最好地标记它已完成?
  • 也许它应该像 http.Response.Body 一样实现 io.Closer 接口吗?

这些问题可能有些愚蠢,但是在阅读了一段时间后,我无法理解。也许有更好的实现方式,我不清楚。谢谢!

英文:

After reading a lot about readers/writers in go, I'm now a bit confused on how to implement a custom io.ReadWriter that reads (and blocks) until it is marked as finished. A sample implementation looks like this:

<!-- language: go -->

var rw io.ReadWriter // my custom ReadWriter

// write to it in a non blocking way:
go func() {
    fmt.Fprintf(rw, &quot;Line one\n&quot;)
    // ...more writes
    fmt.Fprintf(rw, &quot;END&quot;) // what would be best to mark the writer as finished???
}()

// read from it and block until **encountering finish mark??**
_, _ = io.Copy(dst, rw)

Some related questions:

  • How http.Response.Body marks the body as finished, so io.Copy() knows when to stop reading?
  • What would be the best way to mark it as finished?
  • Maybe it should also be an io.Closer, as the http.Response.Body?

These might be silly questions but I can't wrap my head around it after reading for a while. Also there might be a better way to implement this, I don't know. Thanks!

答案1

得分: 1

如果你的目标是在一个goroutine中写入数据,在另一个goroutine中读取数据,那么可以使用io.Pipe:

r, w := io.Pipe()
go func(w io.WriteCloser) {
    fmt.Fprintf(w, "Line one\n")
    // ...更多写入操作
    w.Close()
}(w)
io.Copy(dst, r)

关闭管道的写入端来表示写入操作已完成。

playground示例

io.Reader返回io.EOF来表示没有更多的数据可用。HTTP响应体的读取器在读取完整个响应体后返回io.EOF。上述管道的读取端在返回所有写入的数据后返回io.EOF。

英文:

If your goal is to write in one goroutine and read from another, then use an io.Pipe:

r, w := io.Pipe()
go func(w io.WriteCloser) {
	fmt.Fprintf(w, &quot;Line one\n&quot;)
	// ...more writes
	w.Close()
}(w)
io.Copy(dst, r)

Close the write side of the pipe to indicate that the writer is done.

playground example

An io.Reader returns io.EOF to indicate that no more data is available. The http response body reader returns io.EOF at the end of the body. The read side of the pipe above returns io.EOF after returning all data from the writer.

答案2

得分: 0

首先,你是在创建一个自定义类型还是只是使用普通的ReadWriter?

  • http.Response.Body 是一个 io.ReadCloser,所以 io.Copy 可以调用它的 Close() 方法。

  • 为了表示结束,你的 ReadWriter 应该写入一个 io.EOF 来表示它已经完成。你可以查看 ReadCloser(以及它的用法),所以也许你想要一个 io.ReadWriteCloser。

  • 很可能是这样的。

Go 的库代码非常易读,不要害怕在文档中点击函数以查看实际源代码。

英文:

First, are you making a custom type or just using a normal ReadWriter?

  • http.Response.Body is an io.ReadCloser so io.Copy can call its Close()

  • To signal the end,have your ReadWriter write an io.EOF to signal it has finished. You should take a look at ReadCloser (and its usages), so maybe you want an io.ReadWriteCloser.

  • Probably

Go's libary code is very readable don't be afraid to click on the functions in the documentation to look at the actual source.

huangapple
  • 本文由 发表于 2016年4月12日 23:03:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/36577128.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定