我对 Go 完全陌生,我正在尝试读取一个二进制文件,一次一个字节或几个字节。文档没有多大帮助,我找不到任何教程或简单的例子(顺便说一句,谷歌怎么会给他们的语言起这样一个不可搜索的名字?)。基本上,我怎样才能打开一个文件,然后将一些字节读入缓冲区?有什么建议吗?
5 回答
对于操作文件,os
包是你的朋友:
f, err := os.Open("myfile")
if err != nil {
panic(err)
}
defer f.Close()
有关文件打开方式的更多控制,请参阅os.OpenFile()
( doc)。
对于读取文件,有很多方法。(上例中的 the )os.File
返回的类型实现了接口(它有一个带有正确签名的方法),它可以直接用于读取缓冲区(a )中的一些数据,也可以包装在缓冲的读取器中(类型)。os.Open
f
io.Reader
Read()
[]byte
bufio.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网站。
高温高压
这是我用来将整个二进制文件读入内存的方法
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
}
例如,要计算文件中零字节的数量:
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)
}
您不能像在 C 中那样异想天开地将原始类型转换为 (char*),因此对于二进制数据的任何类型的(反)序列化,请使用 encoding/binary 包。 http://golang.org/pkg/encoding/binary。我无法改进那里的例子。
下面是一个使用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
}
}