以固定步幅大小将字节读入 Go 缓冲区

Mit*_*ops 3 go

我想在文件名给出的文件中一次读取和处理 1024 个字节。我不明白如何正确构建外循环,尤其是适应缓冲区包含少于 1024 字节的最终步幅

我尝试过的:

fs, _ := os.Open(filename)
defer fs.Close()
n := 1024 // 1kb
buff := make([]byte, n)
for {
    buff = make([]byte, n) // is this initialized correctly?
    n1, err := fs.Read(buff)
    if err != nil {
        if err == io.EOF {
            break
        }
        fmt.Println(err)
        break
    }
    fmt.Println("read n1 bytes...", n1)
    fmt.Println(buff)
}
Run Code Online (Sandbox Code Playgroud)

我看过以下资源:

pet*_*rSO 6

以固定步幅大小将字节读入 Go 缓冲区

在文件名给出的文件中一次读取并处理 1024 个字节。

适应缓冲区将包含少于 1024 字节的最终步长。


对于读取的字节数保证,请使用ioutil.ReadFull. 为了高效地读取流,请使用bufio.Reader. 为了提高效率,分配读缓冲区一次并重新使用它。

例如,

package main

import (
    "bufio"
    "fmt"
    "io"
    "io/ioutil"
    "os"
)

func main() {
    stride := 1024
    filename := testname(stride)

    f, err := os.Open(filename)
    if err != nil {
        fmt.Fprintln(os.Stderr, err)
        return
    }
    defer f.Close()

    r := bufio.NewReader(f)
    buf := make([]byte, 0, stride)
    for {
        n, err := io.ReadFull(r, buf[:cap(buf)])
        buf = buf[:n]
        if err != nil {
            if err == io.EOF {
                break
            }
            if err != io.ErrUnexpectedEOF {
                fmt.Fprintln(os.Stderr, err)
                break
            }
        }

        fmt.Println("read n bytes...", n)
        // process buf
    }
}

func testname(stride int) string {
    f, err := ioutil.TempFile("", "test.stride.")
    if err != nil {
        panic(err)
    }
    defer f.Close()
    _, err = f.Write(make([]byte, 2*stride+stride/2))
    if err != nil {
        panic(err)
    }
    return f.Name()
}
Run Code Online (Sandbox Code Playgroud)

游乐场:https://play.golang.org/p/iYOY-z7hkoz

输出:

read n bytes... 1024
read n bytes... 1024
read n bytes... 512
Run Code Online (Sandbox Code Playgroud)