jee said

Go语言文件操作

unclejee & AI
1347 words
7min read
Go语言文件操作

Go语言文件操作

Go语言的os和io包提供了丰富的文件操作功能。本文将介绍Go语言中常见的文件操作。

文件读取

读取整个文件

import (
    "fmt"
    "os"
)

func main() {
    // 读取整个文件
    data, err := os.ReadFile("test.txt")
    if err != nil {
        fmt.Println("读取文件失败:", err)
        return
    }
    fmt.Println(string(data))
}

使用os.Open读取

func main() {
    // 打开文件
    file, err := os.Open("test.txt")
    if err != nil {
        fmt.Println("打开文件失败:", err)
        return
    }
    defer file.Close()

    // 读取文件内容
    data := make([]byte, 1024)
    n, err := file.Read(data)
    if err != nil {
        fmt.Println("读取失败:", err)
        return
    }
    fmt.Println(string(data[:n]))
}

使用bufio逐行读取

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    file, err := os.Open("test.txt")
    if err != nil {
        fmt.Println("打开文件失败:", err)
        return
    }
    defer file.Close()

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

    if err := scanner.Err(); err != nil {
        fmt.Println("扫描错误:", err)
    }
}

文件写入

写入整个文件

import (
    "fmt"
    "os"
)

func main() {
    // 写入文件(覆盖)
    err := os.WriteFile("output.txt", []byte("Hello, World!"), 0644)
    if err != nil {
        fmt.Println("写入文件失败:", err)
        return
    }
    fmt.Println("写入成功")
}

使用os.Create写入

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

    // 写入内容
    _, err = file.WriteString("Hello, Go!")
    if err != nil {
        fmt.Println("写入失败:", err)
        return
    }
}

追加内容

func main() {
    // 以追加模式打开文件
    file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        fmt.Println("打开文件失败:", err)
        return
    }
    defer file.Close()

    // 追加内容
    _, err = file.WriteString("新的日志条目\n")
    if err != nil {
        fmt.Println("写入失败:", err)
        return
    }
}

文件信息

获取文件信息

func main() {
    info, err := os.Stat("test.txt")
    if err != nil {
        fmt.Println("获取文件信息失败:", err)
        return
    }

    fmt.Println("文件名:", info.Name())
    fmt.Println("文件大小:", info.Size())
    fmt.Println("修改时间:", info.ModTime())
    fmt.Println("是否目录:", info.IsDir())
    fmt.Println("权限:", info.Mode())
}

检查文件是否存在

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

func main() {
    if fileExists("test.txt") {
        fmt.Println("文件存在")
    } else {
        fmt.Println("文件不存在")
    }
}

目录操作

创建目录

func main() {
    // 创建单个目录
    err := os.Mkdir("newdir", 0755)
    if err != nil {
        fmt.Println("创建目录失败:", err)
        return
    }

    // 创建多级目录
    err = os.MkdirAll("path/to/nested/dir", 0755)
    if err != nil {
        fmt.Println("创建目录失败:", err)
        return
    }
}

读取目录

func main() {
    // 读取目录
    entries, err := os.ReadDir(".")
    if err != nil {
        fmt.Println("读取目录失败:", err)
        return
    }

    for _, entry := range entries {
        fmt.Println(entry.Name())
        if entry.IsDir() {
            fmt.Println("  (目录)")
        } else {
            fmt.Printf("  (文件, 大小: %d)\n", entry.Size())
        }
    }
}

删除文件和目录

func main() {
    // 删除文件
    err := os.Remove("test.txt")
    if err != nil {
        fmt.Println("删除文件失败:", err)
        return
    }

    // 删除目录(必须为空)
    err = os.Remove("emptydir")
    if err != nil {
        fmt.Println("删除目录失败:", err)
        return
    }

    // 删除目录及其内容
    err = os.RemoveAll("dir")
    if err != nil {
        fmt.Println("删除目录失败:", err)
        return
    }
}

路径操作

filepath包

import (
    "fmt"
    "path/filepath"
)

func main() {
    // 路径拼接
    fullPath := filepath.Join("dir", "subdir", "file.txt")
    fmt.Println(fullPath)  // dir\subdir\file.txt (Windows)

    // 获取文件扩展名
    ext := filepath.Ext("document.pdf")
    fmt.Println(ext)  // .pdf

    // 获取文件名(不含扩展名)
    base := filepath.Base("/path/to/file.txt")
    fmt.Println(base)  // file.txt

    // 获取目录路径
    dir := filepath.Dir("/path/to/file.txt")
    fmt.Println(dir)  // /path/to

    // 获取绝对路径
    abs, err := filepath.Abs("relative/path")
    if err != nil {
        fmt.Println("获取绝对路径失败:", err)
        return
    }
    fmt.Println(abs)
}

文件复制

使用io.Copy

import (
    "io"
    "os"
)

func copyFile(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 main() {
    err := copyFile("source.txt", "destination.txt")
    if err != nil {
        fmt.Println("复制文件失败:", err)
        return
    }
    fmt.Println("复制成功")
}

使用bufio缓冲复制

import (
    "bufio"
    "io"
    "os"
)

func bufferedCopy(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()

    // 使用缓冲区复制
    reader := bufio.NewReader(source)
    writer := bufio.NewWriter(destination)
    defer writer.Flush()

    _, err = io.Copy(writer, reader)
    return err
}

临时文件

创建临时文件

import (
    "fmt"
    "os"
)

func main() {
    // 创建临时文件
    tempFile, err := os.CreateTemp("", "example")
    if err != nil {
        fmt.Println("创建临时文件失败:", err)
        return
    }
    defer os.Remove(tempFile.Name())

    // 写入临时文件
    _, err = tempFile.WriteString("临时内容")
    if err != nil {
        fmt.Println("写入失败:", err)
        return
    }

    fmt.Println("临时文件路径:", tempFile.Name())
}

最佳实践

  1. 使用defer关闭文件:确保文件资源被正确释放
  2. 检查错误:不要忽略文件操作返回的错误
  3. 使用缓冲区:大文件操作使用bufio提高性能
  4. 使用filepath包:处理路径时使用filepath而非字符串拼接
  5. 设置正确的权限:创建文件和目录时设置合适的权限

总结

Go语言的文件操作API简洁而强大,通过os、io和bufio等包,可以轻松完成各种文件操作任务。掌握文件操作是Go语言开发的基本技能。