Go 语言文件处理核心基础
Go 语言的文件处理主要依赖标准库的 os 包(核心文件操作)、io/ioutil(Go1.16 后被移入 io 和 os 包)、bufio(带缓冲的读写),下面按 "读、写、改、查" 的逻辑讲解核心操作。
1. 文件的基本读取
读取文件是最基础的操作,Go 提供了多种读取方式,适配不同场景:
方式 1:一次性读取整个文件(小文件首选)
适合文件体积小的场景,一行代码即可读取全部内容:
Go
package main
import (
"fmt"
"os"
)
func main() {
// 读取文件全部内容,返回字节切片和错误
content, err := os.ReadFile("test.txt")
if err != nil {
fmt.Printf("读取文件失败:%v\n", err)
return
}
// 将字节切片转为字符串输出
fmt.Println("文件内容:", string(content))
}
方式 2:带缓冲读取(大文件首选)
适合大文件,逐行 / 逐块读取,避免一次性加载到内存导致 OOM:
Go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 打开文件:os.Open默认以只读模式打开,返回文件句柄和错误
file, err := os.Open("large_file.txt")
if err != nil {
fmt.Printf("打开文件失败:%v\n", err)
return
}
// 关键:defer确保函数结束时关闭文件句柄,释放资源
defer file.Close()
// 创建带缓冲的读取器
scanner := bufio.NewScanner(file)
// 逐行读取
lineNum := 1
for scanner.Scan() {
line := scanner.Text() // 获取当前行的字符串
fmt.Printf("第%d行:%s\n", lineNum, line)
lineNum++
}
// 检查读取过程中是否有错误
if err := scanner.Err(); err != nil {
fmt.Printf("读取文件出错:%v\n", err)
}
}
2. 文件的写入
写入文件分为 "覆盖写入" 和 "追加写入",核心用 os.Create(覆盖)或 os.OpenFile(自定义模式):
方式 1:覆盖写入文件
os.Create 会创建文件(不存在则新建,存在则清空):
Go
package main
import (
"fmt"
"os"
)
func main() {
// 写入的内容
content := []byte("Hello Go File!\n这是覆盖写入的内容")
// 写入文件,参数:文件名、内容、权限(0644表示所有者可读可写,其他用户只读)
err := os.WriteFile("output.txt", content, 0644)
if err != nil {
fmt.Printf("写入文件失败:%v\n", err)
return
}
fmt.Println("文件写入成功")
}
方式 2:追加写入文件
需要用 os.OpenFile 指定打开模式为 "追加 + 写入":
Go
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 打开文件:
// os.O_APPEND:追加模式
// os.O_WRONLY:只写模式
// os.O_CREATE:文件不存在则创建
file, err := os.OpenFile("output.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
fmt.Printf("打开文件失败:%v\n", err)
return
}
defer file.Close()
// 创建带缓冲的写入器,提升写入效率
writer := bufio.NewWriter(file)
// 写入内容
_, err = writer.WriteString("\n这是追加的内容")
if err != nil {
fmt.Printf("写入内容失败:%v\n", err)
return
}
// 关键:缓冲写入需要刷新,否则内容可能留在缓冲区未写入文件
writer.Flush()
fmt.Println("内容追加成功")
}
3. 文件的常用操作(改、查、删)
除了读写,日常还会用到文件重命名、删除、查看信息等操作:
Go
package main
import (
"fmt"
"os"
"time"
)
func main() {
//2、文件操作
// 2.1 重命名文件
err := os.Rename("F:\\CompanyFiles\\go_output_file.txt", "F:\\CompanyFiles\\go_output_file2.txt")
if err != nil {
fmt.Printf("Error renaming file: %v\n", err)
}
//2.2 获取文件信息(文件大小、修改时间、是否是目录等)
fileInfo, err := os.Stat("F:\\CompanyFiles\\go_output_file2.txt")
if err != nil {
fmt.Printf("Error getting file info: %v\n", err)
return
}
fmt.Printf("文件名:%v\n", fileInfo.Name())
fmt.Printf("文件大小%v\n", fileInfo.Size())
fmt.Printf("文件修改时间%v\n", fileInfo.ModTime().Format(time.DateTime))
fmt.Printf("是否是目录:%t\n", fileInfo.IsDir())
//2.3 删除文件
err = os.Remove("F:\\CompanyFiles\\go_output_file2.txt")
if err != nil {
fmt.Printf("Error removing file: %v\n", err)
}
}
4. 目录操作
文件处理常伴随目录操作(创建目录、遍历目录):
Go
package main
import (
"fmt"
"os"
)
func main() {
// 1. 创建目录(0755表示所有者可读可写可执行,其他用户只读可执行)
err := os.Mkdir("test_dir", 0755)
if err != nil {
fmt.Printf("创建目录失败:%v\n", err)
}
// 创建多级目录用 MkdirAll
os.MkdirAll("parent/child/grandchild", 0755)
// 2. 遍历目录
dirEntries, err := os.ReadDir("test_dir")
if err != nil {
fmt.Printf("遍历目录失败:%v\n", err)
return
}
for _, entry := range dirEntries {
fmt.Printf("名称:%s,是否是目录:%t\n", entry.Name(), entry.IsDir())
}
}
总结
Go 语言文件处理的核心要点:
- 核心包 :
os包是基础(打开、读写、删除、重命名),bufio适合大文件缓冲读写,替代了旧的ioutil; - 资源释放 :打开文件后必须用
defer file.Close()释放句柄,避免资源泄漏; - 写入注意 :缓冲写入(
bufio.Writer)需要调用Flush()确保内容落地,追加写入需指定os.O_APPEND模式。