云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

golang标准库每日一库之os(go语言标准库)

jxf315 2025-06-23 20:06:47 教程文章 3 ℃

一、文件操作(File I/O)

1. 基础文件操作

函数/方法

作用描述

os.Create(filename)

创建文件(覆盖已存在文件),返回 *os.File

os.Open(filename)

以只读模式打开文件

os.OpenFile(name, flag, perm)

高级打开方式(指定标志和权限)

file.Read(b []byte)

读取文件内容到字节数组

file.Write(b []byte)

写入字节数组到文件

file.Close()

关闭文件(必须显式调用,避免资源泄漏)

os.Remove(filename)

删除文件

文件打开模式(常用组合)

os.O_RDONLY  // 只读
os.O_WRONLY  // 只写
os.O_CREATE  // 不存在则创建
os.O_APPEND  // 追加模式
os.O_TRUNC   // 打开时清空文件
os.O_EXCL    // 与O_CREATE配合,文件必须不存在

示例代码

// 创建并写入文件
file, err := os.Create("data.txt")
if err != nil {
    panic(err)
}
defer file.Close()
file.WriteString("Hello, OS Package!\n")

// 读取文件内容
content, err := os.ReadFile("data.txt")  // 快捷方法(Go 1.16+)
if err == nil {
    fmt.Println(string(content))  // "Hello, OS Package!"
}

二、目录操作(Directory)

1. 目录管理方法

函数

作用描述

os.Mkdir(name, perm)

创建单级目录(权限如0755)

os.MkdirAll(path, perm)

递归创建多级目录

os.ReadDir(dirname)

读取目录内容(返回[]DirEntry)

os.Remove(dirname)

删除空目录

os.RemoveAll(path)

递归删除目录及其内容

os.Rename(oldpath, newpath)

重命名/移动文件或目录

示例代码

// 递归创建目录
if err := os.MkdirAll("project/logs/2023", 0755); err != nil {
    log.Fatal(err)
}

// 遍历目录
entries, _ := os.ReadDir("project")
for _, entry := range entries {
    fmt.Println(entry.Name(), entry.IsDir())
}

// 删除整个目录树
os.RemoveAll("project")

三、环境变量管理(Environment Variables)

1. 核心方法

函数

作用描述

os.Setenv(key, value)

设置环境变量

os.Getenv(key)

获取环境变量(不存在返回空字符串)

os.LookupEnv(key)

返回变量值和是否存在标志

os.Unsetenv(key)

删除环境变量

os.Environ()

获取所有环境变量(KEY=value格式)

示例代码

// 设置并获取环境变量
os.Setenv("API_KEY", "secret123")
key := os.Getenv("API_KEY")

// 安全获取变量
if dbURL, ok := os.LookupEnv("DB_URL"); ok {
    fmt.Println("Database URL:", dbURL)
} else {
    fmt.Println("DB_URL not set")
}

// 打印所有环境变量
for _, env := range os.Environ() {
    fmt.Println(env)
}

四、进阶技巧与性能优化

1. 高效文件读写

  • 分块读取大文件(避免内存溢出):
file, _ := os.Open("large.log")
defer file.Close()
buffer := make([]byte, 4096)  // 4KB缓冲区
for {
    n, err := file.Read(buffer)
    if err == io.EOF {
        break
    }
    process(buffer[:n])
}
  • 缓冲写入(提升I/O性能):
file, _ := os.Create("output.log")
writer := bufio.NewWriter(file)
defer func() {
    writer.Flush()  // 确保缓冲区数据写入磁盘
    file.Close()
}()
writer.WriteString("Buffered write\n")

2. 文件信息与权限

// 获取文件元数据
info, _ := os.Stat("data.txt")
fmt.Println("Size:", info.Size(), "ModTime:", info.ModTime())

// 修改文件权限
os.Chmod("script.sh", 0755)  // rwxr-xr-x
os.Chown("data.txt", 1000, 1000)  // 设置UID/GID(需权限)

五、常见错误与最佳实践

1. 典型陷阱

  • 资源泄漏:忘记调用file.Close()或未使用defer
// 错误:未关闭文件
file, _ := os.Open("data.txt")
// 正确:使用defer
file, _ := os.Open("data.txt")
defer file.Close()
  • 路径分隔符硬编码
// 错误(Windows不兼容)
path := "data\\file.txt"
// 正确:使用filepath包
path := filepath.Join("data", "file.txt")

2. 安全实践

  • 检查文件是否存在
if _, err := os.Stat("config.yaml"); errors.Is(err, os.ErrNotExist) {
    // 文件不存在时的处理
}
  • 原子写入(避免写入过程中崩溃导致数据损坏):
tmpFile := "data.tmp"
finalFile := "data.txt"
os.WriteFile(tmpFile, data, 0644)
os.Rename(tmpFile, finalFile)  // 原子操作

六、实战示例:配置文件加载器

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func LoadConfig() {
    // 优先从环境变量获取配置路径
    configPath := os.Getenv("CONFIG_PATH")
    if configPath == "" {
        configPath = filepath.Join("etc", "app", "config.yaml")
    }

    // 检查文件是否存在
    if _, err := os.Stat(configPath); err != nil {
        panic("Config file not found: " + configPath)
    }

    // 读取配置内容
    data, err := os.ReadFile(configPath)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Loaded config: \n%s\n", data)
}

func main() {
    os.Setenv("CONFIG_PATH", "custom_config.yaml")
    LoadConfig()
}

七、跨平台注意事项

  1. 路径处理:始终使用filepath.Join()代替手动拼接/或\
  2. 行尾符:\n在Windows中会自动转换为\r\n
  3. 权限位:Windows忽略部分Unix权限标志(如可执行位)

通过掌握 os 包的核心功能,可实现对系统资源的精细控制。建议结合具体场景练习:

  1. 实现日志轮转工具(按日期分割文件)
  2. 开发CLI工具处理目录批量重命名
  3. 编写配置管理模块(环境变量+文件优先级)

Tags:

最近发表
标签列表