go - 除非EOF,否则准确读取n个字节?
问题描述
我正在使用一个返回一个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,因此ErrUnexpectedEOF
如果buf
不能用 2048 字节填充的原因是文件在例如 500 字节之后是 EOF,则不会返回。但是,在任何其他情况下,ErrUnexpectedEOF
应在出现问题时退回。
我能做些什么来做到这一点?
另一个问题是直接从网络读取 2048 字节似乎有很多开销,如果我可以从网络获取 256 KB 到缓冲区,然后从该缓冲区中获取我需要的 2048 字节,那会更好.
解决方案
例如,
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func readChunks(r io.Reader) error {
if _, ok := r.(*bufio.Reader); !ok {
r = bufio.NewReader(r)
}
buf := make([]byte, 0, 2048)
for {
n, err := io.ReadFull(r, buf[:cap(buf)])
buf = buf[:n]
if err != nil {
if err == io.EOF {
break
}
if err != io.ErrUnexpectedEOF {
return err
}
}
// Process buf
fmt.Println(len(buf))
}
return nil
}
func main() {
fName := `test.file`
f, err := os.Open(fName)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
err = readChunks(f)
if err != nil {
fmt.Println(err)
return
}
}
推荐阅读
- python - Python OpenCV 转换后无法正确显示图像
- java - 使用不同枚举的不同值作为键的映射
- ios - iOS 应用程序开发:整个屏幕上的背景图像,包括顶部时间行
- json - Powershell ConvertFrom-Json
- jquery - 如何以编程方式单击 DrawToolbar 上的元素?
- linux - 更改 AWS EC2 实例上的日期/时间会导致服务器在大约一小时内变得无响应
- python - Django extra_views - UpdateWithInlinesView:字段不存在
- wordpress - PHP 7更新后参数必须是实现Countable的数组或对象
- react-spring - react-spring 和 typescript 不可调用错误
- python - 无法从 torchvision 加载数据集