背景
学习笔记:利用Golang对文件进行读写操作
文件操作
一、读操作
- 设置缓冲区的读操作:默认4096缓冲区
bufio.NewReader(),或者自定义缓冲区bufio.NewReaderSize(),适合读取大体量内容的文件。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
// 一个需要读取的txt文件
filePath := "test.txt"
file, err := os.Open(filePath)
if err != nil {
fmt.Println("error msg: ", err)
}
// 延时关闭文件,防止内存泄露
defer func() {
err := file.Close()
if err != nil {
fmt.Println("close file err: ", err)
return
}
}()
// 创建读取缓冲区,默认4096字节
reader := bufio.NewReader(file)
// 创建自定义读取缓冲区,设置2048字节
// reader := bufio.NewReaderSize(file, 2048)
// 循环读取文件内容
for {
content, err := reader.ReadString('\n')
// 判断是否是文件末尾
if err == io.EOF {
break
}
fmt.Print(content)
}
}
- 一次性全量读取操作,适合小体量内容的文件。其中
ioutil.ReadFile()函数内封装了defer file.close(),所以在调用过程中无需再释放文件。
package main
import (
"fmt"
"io/ioutil"
)
func main() {
// 一个需要读取的txt文件
filePath := "test.txt"
// 读取文件内容到内存中,值为[]byte类型
content, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("read file error: ", err)
}
// []byte转string
result := string(content)
fmt.Println(result)
}
- 读取Json文件,创建一个结构体来反序列化Json文件中的内容。
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
type Student struct {
Id int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// json文件的路径
filePath := "test.json"
jsonFile, err := os.Open(filePath)
if err != nil {
fmt.Println("open json file error: ", err)
}
// 延时关闭文件,防止内存泄露
defer func() {
err := jsonFile.Close()
if err != nil {
fmt.Println("close file error: ", err)
}
}()
// 从文件中读取,直到出现错误或EOF,并返回读取的数据
jsonData, err := ioutil.ReadAll(jsonFile)
if err != nil {
fmt.Println("read file error: ", err)
}
// 创建一个student对象
var student Student
// 利用Unmarshal反序列化数据到结构体
err = json.Unmarshal(jsonData, &student)
if err != nil {
fmt.Println("unmarshal json error: ", err)
}
fmt.Println(student)
}
二、写操作
设置缓冲区的写操作:默认4096缓冲区bufio.NewWriter(),或者自定义缓冲区bufio.NewWriterSize()。
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 新文件的路径
filePath := "test.txt"
// 打开一个文件,只写操作,如果没有该文件则自动新增
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Println("open file error: ", err)
}
// 延时关闭文件,防止内存泄露
defer func() {
err := file.Close()
if err != nil {
fmt.Println("close file error: ", err)
}
}()
// 需要写入的string
newStr := "Hello World"
// 使用默认带缓存的*Writer,默认4096字节
writer := bufio.NewWriter(file)
// 使用自定义缓存的*Writer,设置2048字节
// writer := bufio.NewWriterSize(file, 2048)
_, err = writer.WriteString(newStr)
if err != nil {
fmt.Println("write string error: ", err)
}
// 将缓存的内容刷新到文件中
err = writer.Flush()
if err != nil {
fmt.Println("flush error: ", err)
}
}
操作os.OpenFile()函数:
perm FileMode文件权限的选择
0777:-rwxrwxrwx,创建了一个普通文件,所有人拥有所有的读、写、执行权限
0666:-rw-rw-rw-,创建了一个普通文件,所有人拥有对该文件的读、写权限,但是都不可执行
0644:-rw-r--r--,创建了一个普通文件,文件所有者对该文件有读写权限,用户组和其他人只有读权限,没有执行权限
flag int模式的选择
os.O_RDONLY: 以只读的方式打开
os.O_WRONLY: 以只写的方式打开
os.O_RDWR : 以读写的方式打开
os.O_NONBLOCK: 打开时不阻塞
os.O_APPEND: 以追加的方式打开
os.O_CREAT: 创建并打开一个新文件
os.O_TRUNC: 打开一个文件并截断它的长度为零(必须有写权限)
os.O_EXCL: 如果指定的文件存在,返回错误
os.O_SHLOCK: 自动获取共享锁
os.O_EXLOCK: 自动获取独立锁
os.O_DIRECT: 消除或减少缓存效果
os.O_FSYNC : 同步写入
os.O_NOFOLLOW: 不追踪软链接
- 几种常用模式
os.O_WRONLY | os.O_CREATE | O_EXCL 如果已经存在,则失败
os.O_WRONLY | os.O_CREATE 如果已经存在,会覆盖写,不会清空原来的文件,而是从头直接覆盖写
os.O_WRONLY | os.O_CREATE | os.O_APPEND 如果已经存在,则在尾部添加写