我完全不了解 Go 语言,现在想要逐字节或逐段读取一个二进制文件。但是文档并没有提供很多帮助,我也找不到任何教程或简单的示例(顺便问一下,Google 怎么会给他们的语言起这样一个难以搜索的名字呢?)。基本上,我应该如何打开一个文件,并将一些字节读入缓冲区?有什么建议吗?
我完全不了解 Go 语言,现在想要逐字节或逐段读取一个二进制文件。但是文档并没有提供很多帮助,我也找不到任何教程或简单的示例(顺便问一下,Google 怎么会给他们的语言起这样一个难以搜索的名字呢?)。基本上,我应该如何打开一个文件,并将一些字节读入缓冲区?有什么建议吗?
对于文件操作来说,os
包是你的好朋友:
f, err := os.Open("myfile")
if err != nil {
panic(err)
}
defer f.Close()
若想更加精细地控制文件的打开方式,请参阅os.OpenFile()
((doc))。
读取文件有多种方法。通过os.Open
函数打开文件后返回的os.File
类型对象(上述示例中的f
),实现了io.Reader
接口(拥有正确签名的Read()
方法),可以直接用于将一些数据读入缓冲区(一个[]byte
数组),或者也可以被包装在缓存读取器(bufio.Reader
类型)中。
对于二进制数据,encoding/binary
包可能很有用,可以将一系列字节读入某个特定类型的数据结构中。您可以在Go doc here中看到一个示例。由于如前所述,os.Open()
返回的是一个io.Reader
,因此可以使用binary.Read()
函数与该函数读取的文件一起使用。
还有一个简单易用的io/ioutil
包,允许您一次读取整个文件为字节切片(ioutil.ReadFile()
,它需要一个文件名,因此您甚至不必自己打开/关闭文件),或者ioutil.ReadAll()
,它需要一个io.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
}
io/ioutil
包中的 func ReadFile(filename string) ([]byte, error)
函数呢? - peterSObytes
作为 []byte
的名称,因为这也是一个库的名称,也许取一些其他的名称会更好,比如 byteArray
或者其他类似的名称,除此之外,这个代码可以正常工作。 - Cesar Celispackage 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)
}
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
}
}