How to read arbitrary amounts of data directly from a file in Go?

huangapple go评论76阅读模式
英文:

How to read arbitrary amounts of data directly from a file in Go?

问题

不需要将文件内容读入内存,我如何从文件中读取“x”字节,以便我可以为每个单独的读取操作指定x是多少?

我看到各种ReaderRead方法接受一个特定长度的字节切片,我可以从文件中读取到该切片中。但在这种情况下,切片的大小是固定的,而我希望做的是:

func main() {
	f, err := os.Open("./file.txt")
	if err != nil {
		panic(err)
	}

	someBytes := f.Read(2)
	someMoreBytes := f.Read(4)
}

bytes.Buffer有一个Next方法,它的行为非常接近我想要的,但它需要一个现有的缓冲区才能工作,而我希望在不需要将整个文件读入内存的情况下读取任意数量的字节。

如何最好地实现这一点?

谢谢您的时间。

英文:

Without reading the contents of a file into memory, how can I read "x" bytes from the file so that I can specify what x is for every separate read operation?

I see that the Read method of various Readers takes a byte slice of a certain length and I can read from a file into that slice. But in that case the size of the slice is fixed, whereas what I would like to do, ideally, is something like:

func main() {
	f, err := os.Open("./file.txt")
	if err != nil {
		panic(err)
	}

	someBytes := f.Read(2)
	someMoreBytes := f.Read(4)
}

bytes.Buffer has a Next method which behaves very closely to what I would want, but it requires an existing buffer to work, whereas I'm hoping to read an arbitrary amount of bytes from a file without needing to read the whole thing into memory.

What is the best way to accomplish this?

Thank you for your time.

答案1

得分: 2

使用这个函数:

// readN从读取器中读取并返回n个字节。
// 如果出错,readN返回部分读取的字节和非nil的错误。
func readN(r io.Reader, n int) ([]byte, error) {
    // 为结果分配缓冲区
    b := make([]byte, n)
    // ReadFull确保缓冲区被填满或返回错误。
    n, err := io.ReadFull(r, b) 
    return b[:n], err
}

像这样调用:

someBytes, err := readN(f, 2)
if err != nil  { /* 在这里处理错误 */
someMoreBytes := readN(f, 4)
if err != nil  { /* 在这里处理错误 */
英文:

Use this function:

// readN reads and returns n bytes from the reader.
// On error, readN returns the partial bytes read and
// a non-nil error.
func readN(r io.Reader, n int) ([]byte, error) {
	// Allocate buffer for result
	b := make([]byte, n)
    // ReadFull ensures buffer is filled or error is returned.
	n, err := io.ReadFull(r, b) 
	return b[:n], err
}

Call like this:

someBytes, err := readN(f, 2)
if err != nil  { /* handle error here */
someMoreBytes := readN(f, 4)
if err != nil  { /* handle error here */

答案2

得分: 0

你可以这样做:

f, err := os.Open("/tmp/dat")
check(err)
b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))

更多阅读请查看这个网站

英文:

you can do something like this:

f, err := os.Open("/tmp/dat")
check(err)
b1 := make([]byte, 5)
n1, err := f.Read(b1)
check(err)
fmt.Printf("%d bytes: %s\n", n1, string(b1[:n1]))

for more reading please check site.

huangapple
  • 本文由 发表于 2022年10月30日 14:01:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/74250873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定