英文:
convert from `bufio.Reader` to `io.ReadWriteCloser`
问题
我有一个io.ReadWriteCloser
,我想在不推进读取器的情况下查看其中的内容,
所以我正在使用
bi := bufio.NewReader(i)
bi.Peek(1)
到目前为止还好,但是后来当我想要重新使用原始的io.ReadWriteCloser
(i
)时,它只有EOF
。
所以我的问题是如何将bufio.Reader
转换回io.ReadWriteCloser
。
英文:
I have an io.ReadWriteCloser
in which I want to peek into it without advancing the reader,
so I am using
bi := bufio.NewReader(i)
bi.Peek(1)
So far so good, but later when I want to reuse the original io.ReadWriteCloser
(i
) it has only EOF
.
So my question is how to convert back from bufio.Reader
back to io.ReadWriteCloser
答案1
得分: 3
因为bufio.Reader从底层读取器缓冲数据,所以在调用Peek后,应用程序必须从bufio.Reader中读取。
要获得执行此操作的io.ReadWriteCloser,请包装bufio.Reader和原始的io.ReadWriteCloser:
// BufferedReadWriteCloser具有*bufio.Reader和io.ReadWriteCloser的所有方法。
type BufferedReadWriteCloser struct {
*bufio.Reader
io.ReadWriteCloser
}
func (rw *BufferedReadWriteCloser) Read(p []byte) (int, error) {
return rw.Reader.Read(p)
}
以下是如何使用它的示例:
rw := &BufferedReadWriteCloser{bufio.NewReader(i), i}
p, err := rw.Peek(1)
rw
的值满足io.ReadWriteCloser接口的要求。
并不要求或假设io.ReadWriteCloser具有Seek方法。
英文:
Because the bufio.Reader buffers data from the underlying reader, the application must read from the bufio.Reader after the call to Peek.
To get an io.ReadWriteCloser that does this, wrap the bufio.Reader and the original io.ReadWriteCloser:
// BufferedReadWriteCloser has all of the methods
// from *bufio.Reader and io.ReadWriteCloser.
type BufferedReadWriteCloser struct {
*bufio.Reader
io.ReadWriteCloser
}
func (rw *BufferedReadWriteCloser) Read(p []byte) (int, error) {
return rw.Reader.Read(p)
}
Here's how to use it:
rw := &BufferedReadWriteCloser{bufio.NewReader(i), i}
p, err := rw.Peek(1)
The value of rw
satisfies the io.ReadWriteCloser interface.
There is no requirement or assumption that the io.ReadWriteCloser has a Seek method.
答案2
得分: 0
如上面我的评论中提到的,你需要访问原始读取器的Seek
方法。这意味着将读取器作为io.ReadWriteCloser
传递是不够的。话虽如此,下面的辅助函数可能是一个解决方法:
func peek(r io.Reader, n int) ([]byte, error) {
bi := bufio.NewReader(r)
peeked, err := bi.Peek(n)
if err != nil {
return nil, err
}
// 使用类型断言来检查r是否实现了io.Seeker接口。如果是,则使用它来重置偏移量。
if seeker, ok := r.(io.Seeker); ok {
seeker.Seek(0, 0)
}
return peeked, nil
}
现在你可以将io.ReadWriteCloser
传递给这个peek
函数。peek
函数会检查读取器是否实现了Seek
方法。如果实现了Seek
方法,peek
函数将调用它。
英文:
As mentioned in my comment above, you need access to the original reader's Seek
method. This means that passing the reader around as an io.ReadWriteCloser
is insufficient. Having said that, the following helper function may be a workaround:
func peek(r io.Reader, n int) ([]byte, error) {
bi := bufio.NewReader(r)
peeked, err := bi.Peek(n)
if err != nil {
return nil, err
}
// Use type assertion to check if r implements the
// io.Seeker interface. If it does, then use it to
// reset the offset.
if seeker, ok := r.(io.Seeker); ok {
seeker.Seek(0, 0)
}
return peeked, nil
}
Now you can pass the io.ReadWriteCloser
to this peek
function. The peek
function checks if the reader happens to implement the Seek
method. If the Seek
method is implemented, then peek
will call it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论