方法一:使用os.ReadFile
f, err := os.ReadFile("/Users/litxzo/Desktop/0_1682149622.jpeg")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(string(f))
此方法直接返回一个byte数组。
- 注意:在1.6版本后弃用了ioutil.ReadFile,改用os.ReadFile
方法二:先打开文件再ReadAll
f, err := os.Open("/Users/litxzo/Desktop/0_1682149622.jpeg")
if err != nil {
fmt.Println(err.Error())
}
fd, _ := io.ReadAll(f)
defer f.Close()
fmt.Printf("%s", fd)
- 注意ReadAll方法本来在ioutil包中,1.6版本后改到io包中。
方法三:将文件读到reader
先打开文件,再将文件读到reader中,再从reader读到buf中,最后拼到byte数组里。
f, err := os.Open("/Users/litxzo/Desktop/0_1682149622.jpeg")
if err != nil {
fmt.Println(err.Error())
}
defer f.Close()
r := bufio.NewReader(f)
buf := make([]byte, 1024)
var chunk []byte
for {
_, err := r.Read(buf)
fmt.Println(buf)
if err == io.EOF {
break
}
if err != nil {
fmt.Println(err.Error())
}
chunk = append(chunk, buf...)
}
fmt.Println(string(chunk))
方法四:打开文件后read
f, err := os.Open("/Users/litxzo/Desktop/0_1682149622.jpeg")
if err != nil {
fmt.Println(err.Error())
}
defer f.Close()
buf := make([]byte, 1024)
var chunk []byte
for {
_, err := f.Read(buf)
fmt.Println(buf)
if err == io.EOF {
break
}
if err != nil {
fmt.Println(err.Error())
}
chunk = append(chunk, buf...)
}
fmt.Println(string(chunk))
小结
我们打开os.ReadFile的源码:
func ReadFile(name string) ([]byte, error) {
f, err := Open(name)
if err != nil {
return nil, err
}
defer f.Close()
var size int
if info, err := f.Stat(); err == nil {
size64 := info.Size()
if int64(int(size64)) == size64 {
size = int(size64)
}
}
size++ // one byte for final read at EOF
// If a file claims a small size, read at least 512 bytes.
// In particular, files in Linux's /proc claim size 0 but
// then do not work right if read in small pieces,
// so an initial read of 1 byte would not work correctly.
if size < 512 {
size = 512
}
data := make([]byte, 0, size)
for {
if len(data) >= cap(data) {
d := append(data[:cap(data)], 0)
data = d[:len(data)]
}
n, err := f.Read(data[len(data):cap(data)])
data = data[:len(data)+n]
if err != nil {
if err == io.EOF {
err = nil
}
return data, err
}
}
}
他首先打开了文件,接着用f.Stat方法获取了文件的信息,这里Stat返回描述文件的FileInfo结构。再通过返回的info.Size获得文件的长度,再另size++来多存放一个EOF。然后创建一个容量为size的data。用来存放读取的数据。
在循环读取时,这里还考虑了超出容量的异常情况。
本质上ReadFile也是打开文件并直接read的方法。