30

我对 Go 完全陌生,我正在尝试读取一个二进制文件,一次一个字节或几个字节。文档没有多大帮助,我找不到任何教程或简单的例子(顺便说一句,谷歌怎么会给他们的语言起这样一个不可搜索的名字?)。基本上,我怎样才能打开一个文件,然后将一些字节读入缓冲区?有什么建议吗?

4

5 回答 5

27

对于操作文件,os包是你的朋友:

f, err := os.Open("myfile")
if err != nil {
   panic(err)
}
defer f.Close()

有关文件打开方式的更多控制,请参阅os.OpenFile()( doc)

对于读取文件,有很多方法。(上例中的 the )os.File返回的类型实现了接口(它有一个带有正确签名的方法),它可以直接用于读取缓冲区(a )中的一些数据,也可以包装在缓冲的读取器中(类型)。os.Openfio.ReaderRead()[]bytebufio.Reader

特别是对于二进制数据,该encoding/binary包可能很有用,可以将字节序列读取到某种类型的数据结构中。您可以在此处的 Go 文档中查看示例。该binary.Read()函数可以与使用该os.Open()函数读取的文件一起使用,因为正如我所提到的,它是一个io.Reader.

还有一个简单易用的io/ioutil包,它允许你在一个字节片中一次读取整个文件(ioutil.ReadFile(),它需要一个文件名,所以你甚至不必自己打开/关闭文件),或者ioutil.ReadAll()需要aio.Reader并返回包含整个文件的字节切片。这是关于 ioutil 的文档

最后,正如其他人所提到的,您可以使用“golang”搜索 Go 语言,您应该会找到所需的一切。golang -nuts 邮件列表也是一个寻找答案的好地方(发帖前一定要先搜索一下,很多东西已经回答过了)。要查找第三方软件包,请查看godoc.org网站。

高温高压

于 2013-01-25T02:55:31.947 回答
13

这是我用来将整个二进制文件读入内存的方法

func RetrieveROM(filename string) ([]byte, error) {
    file, err := os.Open(filename)

    if err != nil {
        return nil, err
    }
    defer file.Close()

    stats, statsErr := file.Stat()
    if statsErr != nil {
        return nil, statsErr
    }

    var size int64 = stats.Size()
    bytes := make([]byte, size)

    bufr := bufio.NewReader(file)
    _,err = bufr.Read(bytes)

    return bytes, err
}
于 2013-01-28T21:43:26.780 回答
10

例如,要计算文件中零字节的数量:

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    f, err := os.Open("filename")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    data := make([]byte, 4096)
    zeroes := 0
    for {
        data = data[:cap(data)]
        n, err := f.Read(data)
        if err != nil {
            if err == io.EOF {
                break
            }
            fmt.Println(err)
            return
        }
        data = data[:n]
        for _, b := range data {
            if b == 0 {
                zeroes++
            }
        }
    }
    fmt.Println("zeroes:", zeroes)
}
于 2013-01-25T07:55:31.657 回答
3

您不能像在 C 中那样异想天开地将原始类型转换为 (char*),因此对于二进制数据的任何类型的(反)序列化,请使用 encoding/binary 包。 http://golang.org/pkg/encoding/binary。我无法改进那里的例子。

于 2013-03-06T17:54:24.830 回答
0

下面是一个使用Read方法的例子:

package main

import (
   "io"
   "os"
)

func main() {
   f, e := os.Open("a.go")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   for {
      b := make([]byte, 10)
      _, e = f.Read(b)
      if e == io.EOF {
         break
      } else if e != nil {
         panic(e)
      }
      // do something here
   }
}

https://golang.org/pkg/os#File.Read

于 2021-04-09T04:03:09.887 回答