如何在Go中读取二进制文件

时间:2013-01-25 02:05:37

标签: file-io go

我是Go的新手,我正在尝试逐字节读取二进制文件或一次读取几个字节。文档没有多大帮助,我找不到任何教程或简单的例子(顺便说一句,Google如何为他们的语言提供这样一个不可哄骗的名字?)。基本上,我如何打开文件,然后将一些字节读入缓冲区?有什么建议吗?

5 个答案:

答案 0 :(得分:19)

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

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

要更好地控制文件的打开方式,请参阅os.OpenFile()而不是(doc)

对于阅读文件,有很多方法。 os.File返回的os.Open类型(上例中的f)实现了io.Reader接口(它具有带有正确签名的Read()方法),它可以直接用于读取缓冲区中的一些数据([]byte),也可以用缓冲读取器(类型bufio.Reader)包装。

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

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

最后,正如其他人提到的,你可以使用“golang”谷歌关于Go语言,你应该找到所需的一切。 golang-nuts mailing list也是寻找答案的好地方(确保在发布前先搜索,已经回答了很多内容)。要查找第三方软件包,请查看godoc.org网站。

HTH

答案 1 :(得分:9)

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

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
}

答案 2 :(得分:7)

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

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)
}

答案 3 :(得分:0)

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

答案 4 :(得分: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