看来你不清楚你需要做什么的概念。
您需要创建一个函数具有以下签名:
func LimitReader(r io.Reader, n int64) io.Reader
也就是说,r
io.Reader
和n
数传递给它,你必须返回一个新的io.Reader
。当有人从返回阅读器读取,读取的数据必须来自通过r
阅读器,它应该自动计数读取字节;并且如果读取字节超过n
号码,则其不得从r
读取更多字节,但返回io.EOF
,其用于指示到达流的末尾。可能是因为r
阅读器有更多的字节(意味着可以从中读取更多的字节),但不应读取和返回:这就是LimitedReader
的用途。
如果您认为您现在已经了解该问题,请立即停止阅读答案,并尝试自行实施。以下是一个示例解决方案。
这个确切的功能已经存在于io
包,并通过同名云:io.LimitReader()
。
// LimitReader returns a Reader that reads from r
// but stops with EOF after n bytes.
// The underlying implementation is a *LimitedReader.
func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
它返回的*io.LimitedReader
的值,它的实现是这样的:
// A LimitedReader reads from R but limits the amount of
// data returned to just N bytes. Each call to Read
// updates N to reflect the new amount remaining.
type LimitedReader struct {
R Reader // underlying reader
N int64 // max bytes remaining
}
func (l *LimitedReader) Read(p []byte) (n int, err error) {
if l.N <= 0 {
return 0, EOF
}
if int64(len(p)) > l.N {
p = p[0:l.N]
}
n, err = l.R.Read(p)
l.N -= int64(n)
return
}
需要一分钟或2至尝试自己理解代码。如果你被卡住或者没有一切都清楚,请继续阅读。
解释的代码:
io.LimitedReader
是一个结构,其中包含源读者它从读取,并且可以仍然不必报告io.EOF
读取的字节数。因此,LimitReader()
只是简单地返回此结构的值,其中参数r
和n
被分配给结构的字段R
和N
。更具体地说,返回该结构的地址,因为LimitedReader.Read()
具有指针接收器,因此只有指向它的指针实现io.Reader
。它有一个指针接收器,因为Read()
方法(可能)修改结构的字段,所以需要一个指针才能做到这一点(否则只有一个副本会被修改,在Read()
方法返回后将被丢弃)。
LimitedReader.Read()
首先检查N
领域,它告诉我们多少字节可以退货,如果没有更多的“允许”,是一个乖巧有限公司阅读器,它返回io.EOF
immedately不读从更多的数据来源:
if l.N <= 0 {
return 0, EOF
}
如果N
为正,这意味着一些字节可以读取和返回,但不超过N
,所以如果p
片传递给Read()
具有更大的长度,我们重新切片这么给源阅读器的调用将无法读取超过了我们应该允许:
if int64(len(p)) > l.N {
p = p[0:l.N]
}
而最后一部分是什么更多的,真正做阅读,从源头读者:
n, err = l.R.Read(p)
它返回实际读取的字节数和一个可选错误(无论读取是否遇到一些错误)。由于我们即将返回这些,我们有管理的字节这个量现在回来了,我们必须从允许的剩余字节减去此:
l.N -= int64(n)
return
你有一个具体的问题,我们可以帮助您? – jcbwlkr
也许看看[io.Reader]的文档(https://golang.org/pkg/io/#Reader) – jcbwlkr
我认为最好是编写自己的代码(尽管不完整或不工作),并要求http://codereview.stackexchange.com/的评论。 – philipjkim