引入

程序不是孤立运行的,它需要和操作系统打交道——读取环境变量获取配置、操作文件读写数据、解析命令行参数控制行为、异常时退出进程。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.OpenFile
  • os.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 抽象和流式数据处理。