gpt4 book ai didi

go - 除非 EOF,否则只读取 n 个字节?

转载 作者:IT王子 更新时间:2023-10-29 02:09:12 25 4
gpt4 key购买 nike

我正在使用返回 io.Reader 的函数从 Internet 下载文件。

我想以正好 2048 个 block 的形式处理文件,直到由于 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 字节的倍数,因此最后一个 block 可能只是例如500 字节,io.ReadFull 将因此返回 ErrUnexpectedEOF 并丢弃最后一个 block 。

总结我想要的函数名可以是io.ReadFullUnlessLastChunk,所以ErrUnexpectedEOF不会因为buf不能返回填充了 2048 字节,是文件在 e.g. 之后是 EOF 500 字节。但是,在任何其他情况下,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
}
}

关于go - 除非 EOF,否则只读取 n 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52209430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com