Go 文件操作完全指南

Go 语言提供了强大且简洁的文件操作功能,主要通过 osiobufio 等标准库实现。下面我将详细介绍 Go 中的各种文件操作方法。

1. 基本文件操作

创建文件

package main

import (
    "fmt"
    "os"
)

func main() {
    // 创建文件
    file, err := os.Create("test.txt")
    if err != nil {
        fmt.Println("创建文件失败:", err)
        return
    }
    defer file.Close()
    fmt.Println("文件创建成功")
}

打开文件

// 以只读方式打开
file, err := os.Open("test.txt")

// 以读写方式打开
file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)

// 常用打开模式:
// os.O_RDONLY: 只读
// os.O_WRONLY: 只写
// os.O_RDWR:   读写
// os.O_APPEND: 追加
// os.O_CREATE: 如果不存在则创建
// os.O_TRUNC:  打开时清空文件

写入文件

// 方法1: 使用 Write 和 WriteString
content := "Hello, Go!\n"
n, err := file.Write([]byte(content))
// 或者
n, err := file.WriteString(content)

// 方法2: 使用 fmt.Fprintf
fmt.Fprintf(file, "Number: %d, String: %s\n", 42, "Go")

// 方法3: 使用 bufio.Writer
writer := bufio.NewWriter(file)
writer.WriteString("Buffered writing\n")
writer.Flush() // 记得刷新缓冲区

读取文件

// 方法1: 读取整个文件
data, err := os.ReadFile("test.txt")
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(data))

// 方法2: 逐行读取
file, err := os.Open("test.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

// 方法3: 使用缓冲区读取
buffer := make([]byte, 1024)
for {
    n, err := file.Read(buffer)
    if err == io.EOF {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    fmt.Print(string(buffer[:n]))
}

文件信息

fileInfo, err := os.Stat("test.txt")
if err != nil {
    log.Fatal(err)
}

fmt.Println("文件名:", fileInfo.Name())
fmt.Println("文件大小:", fileInfo.Size(), "bytes")
fmt.Println("修改时间:", fileInfo.ModTime())
fmt.Println("是否是目录:", fileInfo.IsDir())

2. 目录操作

创建目录

// 创建单个目录
err := os.Mkdir("mydir", 0755)

// 创建多级目录
err := os.MkdirAll("path/to/dir", 0755)

读取目录

// 读取目录内容
entries, err := os.ReadDir(".")
if err != nil {
    log.Fatal(err)
}

for _, entry := range entries {
    fmt.Println(entry.Name(), entry.IsDir())
}

遍历目录

func walkDir(path string) {
    err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        if !info.IsDir() {
            fmt.Println("文件:", path)
        } else {
            fmt.Println("目录:", path)
        }
        return nil
    })
    if err != nil {
        log.Fatal(err)
    }
}

3. 文件操作实用示例

复制文件

func copyFile(src, dst string) error {
    input, err := os.ReadFile(src)
    if err != nil {
        return err
    }
    
    err = os.WriteFile(dst, input, 0644)
    if err != nil {
        return err
    }
    return nil
}

// 或者使用 io.Copy 处理大文件
func copyFileLarge(src, dst string) error {
    source, err := os.Open(src)
    if err != nil {
        return err
    }
    defer source.Close()

    destination, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer destination.Close()

    _, err = io.Copy(destination, source)
    return err
}

检查文件是否存在

func fileExists(filename string) bool {
    info, err := os.Stat(filename)
    if os.IsNotExist(err) {
        return false
    }
    return !info.IsDir()
}

删除文件/目录

// 删除文件
err := os.Remove("file.txt")

// 删除目录及其内容
err := os.RemoveAll("directory")

4. 临时文件和目录

// 创建临时文件
tempFile, err := os.CreateTemp("", "example.*.txt")
if err != nil {
    log.Fatal(err)
}
defer os.Remove(tempFile.Name()) // 清理

// 创建临时目录
tempDir, err := os.MkdirTemp("", "example")
if err != nil {
    log.Fatal(err)
}
defer os.RemoveAll(tempDir) // 清理

5. 文件权限

// 更改文件权限
err := os.Chmod("file.txt", 0644)

// 更改文件所有者
err := os.Chown("file.txt", os.Getuid(), os.Getgid())

// 获取当前文件权限
fileInfo, _ := os.Stat("file.txt")
mode := fileInfo.Mode()
fmt.Printf("权限: %o\n", mode.Perm()) // 输出八进制权限

6. 错误处理最佳实践

func handleFileOperation() error {
    file, err := os.Open("file.txt")
    if err != nil {
        return fmt.Errorf("打开文件失败: %w", err)
    }
    defer file.Close()

    // 文件操作...
    return nil
}

总结

Go 的文件操作接口设计简洁而强大,关键点包括:

  1. 总是检查错误:文件操作很容易出错,必须处理错误
  2. 使用 defer 关闭文件:确保资源得到释放
  3. 根据需求选择读写方式:小文件可用 ReadFile/WriteFile,大文件用流式处理
  4. 注意文件权限:特别是在多用户环境中
  5. 处理好路径分隔符:使用 filepath 包来处理跨平台路径问题

这些基础操作应该能够满足大多数文件处理需求。对于更复杂的场景,还可以结合 encodingcompress 等包来处理特定格式的文件。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容