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