【发布时间】:2018-09-07 04:30:39
【问题描述】:
我正在使用返回 io.Reader 的函数从 Internet 下载文件。
我想以精确的 2048 个块处理文件,直到由于 EOF 而不再可能。
io.ReadFull 函数几乎就是我想要的:
buf := make([]byte, 2048)
for {
if _, err := io.ReadFull(reader, buf); err == io.EOF {
return io.ErrUnexpectedEOF
} else if err != nil {
return err
}
// Do processing on buf
}
问题在于并非所有文件都是 2048 字节的倍数,因此最后一个块可能只是例如500 字节,io.ReadFull 将因此返回 ErrUnexpectedEOF 并且最后一个块被丢弃。
总结我想要的函数名称可能是io.ReadFullUnlessLastChunk,所以如果buf不能用2048字节填充,则不会返回ErrUnexpectedEOF,是文件是EOF 之后,例如500 字节。但是,在任何其他情况下,ErrUnexpectedEOF 应在出现问题时返回。
我该怎么做才能做到这一点?
另一个问题是直接从网络读取 2048 字节似乎有很多开销,如果我可以从网络获取 256 KB 到缓冲区,然后从该缓冲区获取我需要的 2048 字节,那会更好。
【问题讨论】:
-
io.LimitReader 对你不起作用有什么原因吗?
-
ReadFull() 不会丢弃最后一个块。它读取剩余数据但也返回 EOF 错误。
-
你似乎知道你想要的确切行为,这不是一个典型的用例——为什么不直接实现只需要很少几行代码的功能呢?
-
@BillSmith124:您可以单击文档中的函数,它会显示源代码(或在您使用的任何编辑器中转到定义):golang.org/src/io/io.go?s=10817:10883#L294 - 只需删除不需要的条件。
-
@BillSmith124:是什么给了你这样的印象?