引入
程序不是孤立运行的,它需要和操作系统打交道——读取环境变量获取配置、操作文件读写数据、解析命令行参数控制行为、异常时退出进程。os 包就是 Go 提供的操作系统交互层,屏蔽了不同平台的差异,提供统一的 API。
正文
定义
定义
os包提供与操作系统交互的功能,包括环境变量读写、文件创建/打开/删除、命令行参数获取、进程退出等。它是 Go 程序访问系统资源的标准入口。
语法
import "os"
// 环境变量
val := os.Getenv("HOME")
os.Setenv("APP_PORT", "8080")
// 文件操作
file, err := os.Open("data.txt")
file, err := os.Create("output.txt")
os.Remove("temp.txt")
// 命令行参数
args := os.Args
// 退出
os.Exit(1)例子
环境变量
// 读取环境变量
home := os.Getenv("HOME")
fmt.Println("HOME:", home)
// 设置环境变量
os.Setenv("APP_ENV", "production")
fmt.Println("APP_ENV:", os.Getenv("APP_ENV")) // production
// 读取环境变量,不存在时返回默认值
port := os.Getenv("PORT")
if port == "" {
port = "3000"
}
fmt.Println("PORT:", port)
// LookupEnv 区分"不存在"和"值为空"
val, exists := os.LookupEnv("MY_VAR")
if exists {
fmt.Println("MY_VAR:", val)
} else {
fmt.Println("MY_VAR 未设置")
}环境变量是程序获取外部配置的最常见方式,尤其在容器化部署中。Getenv 读不到返回空字符串,LookupEnv 能区分”没设置”和”设置了但为空”。
文件操作
// 打开文件(只读)
file, err := os.Open("data.txt")
if err != nil {
fmt.Println("打开失败:", err)
return
}
defer file.Close()
// 创建文件(写入)
file, err = os.Create("output.txt")
if err != nil {
fmt.Println("创建失败:", err)
return
}
defer file.Close()
// 写入内容
file.WriteString("hello world\n")
file.Write([]byte("hello bytes\n"))
// 以追加模式打开
file, err = os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE, 0644)
if err != nil {
return
}
defer file.Close()os.Create 会覆盖已有文件。要追加写入用 os.OpenFile 配合 os.O_APPEND 标志。打开的文件一定要 Close,通常配合 defer 使用。
文件和目录信息
// 判断文件是否存在
info, err := os.Stat("data.txt")
if os.IsNotExist(err) {
fmt.Println("文件不存在")
} else if err != nil {
fmt.Println("其他错误:", err)
} else {
fmt.Println("文件名:", info.Name())
fmt.Println("大小:", info.Size(), "字节")
fmt.Println("是否目录:", info.IsDir())
}
// 读取目录
entries, err := os.ReadDir(".")
if err != nil {
return
}
for _, entry := range entries {
fmt.Println(entry.Name(), entry.IsDir())
}os.Stat 返回文件的元信息,os.IsNotExist 判断是不是”文件不存在”的错误。os.ReadDir 读取目录下的所有条目。
删除和重命名
// 删除文件
err := os.Remove("temp.txt")
if err != nil {
fmt.Println("删除失败:", err)
}
// 重命名/移动文件
err = os.Rename("old.txt", "new.txt")
if err != nil {
fmt.Println("重命名失败:", err)
}命令行参数
func main() {
fmt.Println("所有参数:", os.Args)
fmt.Println("程序路径:", os.Args[0])
if len(os.Args) > 1 {
fmt.Println("第一个参数:", os.Args[1])
}
// 遍历所有参数(跳过程序名)
for i, arg := range os.Args[1:] {
fmt.Printf("参数 %d: %s\n", i, arg)
}
}os.Args 是一个字符串切片,Args[0] 是程序本身的路径,后面的才是用户传入的参数。复杂的命令行参数解析一般用 flag 包。
os.Exit()
if len(os.Args) < 2 {
fmt.Println("用法: myapp <filename>")
os.Exit(1) // 非零退出码表示出错
}
fmt.Println("正常运行...")
os.Exit(0) // 0 表示成功os.Exit() 会立即终止程序,不会执行 defer 函数。退出码 0 表示成功,非零表示出错。
常见写法
| 函数 | 说明 |
|---|---|
os.Getenv(key) | 读取环境变量 |
os.Setenv(key, val) | 设置环境变量 |
os.LookupEnv(key) | 读取环境变量,区分不存在和空值 |
os.Open(name) | 只读打开文件 |
os.Create(name) | 创建/覆盖文件 |
os.OpenFile(name, flag, perm) | 按指定模式打开文件 |
os.Remove(name) | 删除文件或空目录 |
os.Rename(old, new) | 重命名/移动文件 |
os.Stat(name) | 获取文件信息 |
os.IsNotExist(err) | 判断是否文件不存在 |
os.ReadDir(name) | 读取目录内容 |
os.Args | 命令行参数切片 |
os.Exit(code) | 退出进程 |
特点
- 环境变量都是字符串,需要配合 Go strconv 包 转换为其他类型
- 打开文件后必须
Close,用defer是最稳妥的做法 os.Create会覆盖已有文件,追加写入要用os.OpenFileos.Exit()会跳过defer,需要清理资源时先手动Close再退出os.Args[0]是程序路径,不是用户参数os.Stat配合os.IsNotExist是判断文件是否存在的标准写法os包的 API 在不同平台上行为一致,跨平台开发不用操心
理解
os 包是 Go 程序和操作系统之间的桥梁。环境变量用于外部配置,文件操作用于数据读写,命令行参数用于控制程序行为,os.Exit 用于异常退出。日常开发中用得最多的是环境变量和文件操作,记住打开文件要 defer Close,环境变量要检查空值就够了。
引出
os.Open 打开文件后,读文件内容的方式就是通过 io 接口。接下来看 Go io 包,学习 Go 里最重要的 Reader / Writer 抽象和流式数据处理。