整个文件读入内存中
使用 ioutil.ReadFile
package main
import (
"io/ioutil"
"fmt"
)
func main() {
content, err := ioutil.ReadFile("a.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}
使用os.ReadFile
package main
import (
"fmt"
"os"
)
func main() {
content, err := os.ReadFile("a.txt")
if err != nil {
panic(err)
}
fmt.Println(string(content))
}
使用 ioutil.ReadAll
package main
import (
"os"
"io/ioutil"
"fmt"
)
func main() {
file, err := os.Open("a.txt")
if err != nil {
panic(err)
}
defer file.Close()
content, err := ioutil.ReadAll(file)
fmt.Println(string(content))
}
对于大文件,整个文件一次读取,有内存溢出的问题,因此一般并不推荐一次将整个文件读入到内存中。
每次只读取一行
一次性读取所有的数据,太耗费内存,因此可以指定每次只读取一行数据,工作中我们也需要处理日志类数据。
使用 bufio.ReadBytes
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func main() {
// 创建句柄
fi, err := os.Open("christmas_apple.py")
if err != nil {
panic(err)
}
defer fi.Close()
// 创建 Reader
r := bufio.NewReader(fi)
for {
lineBytes, err := r.ReadBytes('\n')
line := strings.TrimSpace(string(lineBytes))
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF && line == "" {
break
}
fmt.Println(line)
}
}
使用 bufio.ReadString
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func main() {
// 创建句柄
fi, err := os.Open("a.txt")
if err != nil {
panic(err)
}
defer fi.Close()
// 创建 Reader
r := bufio.NewReader(fi)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err != nil && err != io.EOF {
panic(err)
}
if err == io.EOF && line == "" {
break
}
fmt.Println(line)
}
}
块读取
通用的做法是:
- 先创建一个文件句柄,可以使用 os.Open 或者 os.OpenFile
- 然后 bufio.NewReader 创建一个 Reader
- 然后在 for 循环里调用 Reader 的 Read 函数,每次仅读取固定字节数量的数据。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
// 创建句柄
fi, err := os.Open("a.txt")
if err != nil {
panic(err)
}
defer fi.Close()
buf := make([]byte, 1024) // 每次读取 1024 个字节
r := bufio.NewReader(fi)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
fmt.Println(string(buf[:n]))
}
}
使用 syscall 库
os 库本质上也是调用 syscall 库,这里直接使用对于read系统调用的封装。
package main
import (
"fmt"
"sync"
"syscall"
)
func main() {
fd, err := syscall.Open("christmas_apple.py", syscall.O_RDONLY, 0)
if err != nil {
fmt.Println("Failed on open: ", err)
}
defer syscall.Close(fd)
var wg sync.WaitGroup
wg.Add(2)
dataChan := make(chan []byte)
go func() {
wg.Done()
for {
data := make([]byte, 100)
n, _ := syscall.Read(fd, data)
if n == 0 {
break
}
dataChan <- data
}
close(dataChan)
}()
go func() {
defer wg.Done()
for {
select {
case data, ok := <-dataChan:
if !ok {
return
}
fmt.Printf(string(data))
default:
}
}
}()
wg.Wait()
}
网友评论