Golang作为一门高效的后端开发语言,内置了丰富的文件操作相关标准库,开发者可以通过这些库快速实现各类文件处理需求,不需要依赖第三方组件。Golang的文件操作核心围绕os包展开,同时配合io、io_ioutil等包可以完成更复杂的读写逻辑。

Golang文件操作常用包介绍
进行文件操作前,首先需要了解几个核心的标准库:
- os包:提供了创建、打开、删除、重命名文件的基础API,同时可以获取文件属性信息。
- io包:提供了通用的IO读写接口,很多文件操作的方法都实现了该包的接口。
- io_ioutil包:提供了便捷的读写工具方法,适合小文件的快速读写操作,不过Go 1.16之后部分方法被迁移到了os包中。
创建与写入文件
创建文件可以使用os包的Create方法,该方法会返回一个文件句柄,后续可以通过句柄进行写入操作。如果文件已经存在,会清空原有内容。
package main
import (
"os"
)
func main() {
// 创建文件,如果文件存在会清空内容
file, err := os.Create("test.txt")
if err != nil {
// 处理创建文件失败的错误
panic(err)
}
// 函数结束时关闭文件,释放资源
defer file.Close()
// 写入字符串内容
_, err = file.WriteString("这是写入的第一行内容n")
if err != nil {
panic(err)
}
// 写入字节切片内容
content := []byte("这是写入的第二行内容")
_, err = file.Write(content)
if err != nil {
panic(err)
}
}
如果需要以追加模式写入文件,可以使用OpenFile方法指定打开模式,常见的模式参数如下:
| 模式参数 | 含义 |
|---|---|
| os.O_WRONLY | 只写模式打开 |
| os.O_RDONLY | 只读模式打开 |
| os.O_RDWR | 读写模式打开 |
| os.O_APPEND | 追加模式,写入内容到文件末尾 |
| os.O_CREATE | 文件不存在时创建文件 |
| os.O_TRUNC | 打开时清空文件原有内容 |
追加写入的示例代码如下:
package main
import (
"os"
)
func main() {
// 以追加、只写、创建模式打开文件
file, err := os.OpenFile("test.txt", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
panic(err)
}
defer file.Close()
// 追加新内容到文件末尾
_, err = file.WriteString("n这是追加的第三行内容")
if err != nil {
panic(err)
}
}
读取文件内容
读取文件有多种方式,小文件可以直接使用os包的ReadFile方法一次性读取全部内容,大文件则建议逐行或者分块读取。
一次性读取小文件
package main
import (
"fmt"
"os"
)
func main() {
// 一次性读取文件全部内容
content, err := os.ReadFile("test.txt")
if err != nil {
panic(err)
}
// 将字节切片转换为字符串打印
fmt.Println(string(content))
}
逐行读取大文件
大文件一次性读取会占用过多内存,可以使用bufio包的Scanner逐行读取:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
// 以只读模式打开文件
file, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer file.Close()
// 创建Scanner逐行扫描
scanner := bufio.NewScanner(file)
lineNum := 1
for scanner.Scan() {
// 获取当前行内容
line := scanner.Text()
fmt.Printf("第%d行内容:%sn", lineNum, line)
lineNum++
}
// 检查扫描过程中是否有错误
if err := scanner.Err(); err != nil {
panic(err)
}
}
其他常见文件操作
删除文件
删除文件可以使用os包的Remove方法,该方法只能删除文件,不能删除非空目录:
package main
import (
"os"
)
func main() {
err := os.Remove("test.txt")
if err != nil {
panic(err)
}
}
判断文件是否存在
可以通过os.Stat方法获取文件信息,结合错误判断文件是否存在:
package main
import (
"fmt"
"os"
)
func main() {
_, err := os.Stat("test.txt")
if os.IsNotExist(err) {
fmt.Println("文件不存在")
} else if err != nil {
fmt.Println("获取文件信息失败:", err)
} else {
fmt.Println("文件存在")
}
}
获取文件属性
通过os.Stat返回的文件信息对象,可以获取文件大小、修改时间等属性:
package main
import (
"fmt"
"os"
"time"
)
func main() {
fileInfo, err := os.Stat("test.txt")
if err != nil {
panic(err)
}
fmt.Println("文件名:", fileInfo.Name())
fmt.Println("文件大小:", fileInfo.Size(), "字节")
fmt.Println("修改时间:", fileInfo.ModTime().Format("2006-01-02 15:04:05"))
fmt.Println("是否为目录:", fileInfo.IsDir())
}
注意事项
进行文件操作时需要注意几个常见问题:
- 打开文件后一定要记得关闭,否则会造成资源泄露,建议使用defer语句在函数结束时关闭文件。
- 写入操作后如果需要立即读取内容,建议先调用Sync方法将缓冲区的内容刷到磁盘,避免读取到旧数据。
- 操作文件时要做好错误处理,比如文件不存在、权限不足等情况都需要提前处理,避免程序崩溃。
文件操作属于IO密集型操作,在高并发场景下要注意控制并发量,避免大量文件操作占用过多系统资源。