三十的博客

Go 中文件目录基本操作

本文内容基于 AI 生成结果整理,可能包含不准确信息,仅供参考使用。
发布时间
阅读量 加载中...

本文目标

⚠️ 相对路径时是基于执行时的工作目录,而不是代码文件位置

例如:

/home/user/projects/myproject/file/mian.go 存在代码 os.Create("./test.txt")

当你在 /home/user/projects/myproject/ 执行 file/mian.go 的程序时

会在 /home/user/projects/myproject/ 目录下创建 test.txt 文件

文件操作

创建文件

go
file, err := os.Create("./test.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

打开文件

go
file, err := os.Open("test.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

打开文件(带选项)

go
file, err := os.OpenFile("test.txt", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
    log.Fatal(err)
}
defer file.Close()

写入文件

go
content := []byte("Hello, World!\n")
_, err := file.Write(content)
if err != nil {
    log.Fatal(err)
}

读取文件

go
data := make([]byte, 100)
count, err := file.Read(data)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Read %d bytes: %q\n", count, data[:count])

文件信息

go
fileInfo, err := os.Stat("test.txt")
if err != nil {
    log.Fatal(err)
}
fmt.Println("File name:", fileInfo.Name())
fmt.Println("Size:", fileInfo.Size())
fmt.Println("Permissions:", fileInfo.Mode())
fmt.Println("Last modified:", fileInfo.ModTime())
fmt.Println("Is directory:", fileInfo.IsDir())

删除文件

go
err := os.Remove("test.txt")
if err != nil {
    log.Fatal(err)
}

目录操作

创建目录

go
err := os.Mkdir("mydir", 0755)
if err != nil {
    log.Fatal(err)
}

创建多级目录

go
err := os.MkdirAll("parent/child/grandchild", 0755)
if err != nil {
    log.Fatal(err)
}

读取目录

go
entries, err := os.ReadDir(".")
if err != nil {
    log.Fatal(err)
}

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

删除目录

go
err := os.Remove("mydir")
if err != nil {
    log.Fatal(err)
}
只会删除空目录,即使里面存在的是空文件。

删除目录及其内容

go
err := os.RemoveAll("parent")
if err != nil {
    log.Fatal(err)
}

路径操作

虽然 os 包提供了一些路径操作,但更推荐使用 path/filepath 包:

go
import "path/filepath"

// 获取当前工作目录
dir, err := os.Getwd()
if err != nil {
    log.Fatal(err)
}

// 拼接路径
fullPath := filepath.Join(dir, "subdir", "file.txt")

// 获取绝对路径
absPath, err := filepath.Abs("relative/path")
if err != nil {
    log.Fatal(err)
}

// 获取路径的基名
base := filepath.Base("/path/to/file.txt") // "file.txt"

// 获取路径的目录部分
dirPath := filepath.Dir("/path/to/file.txt") // "/path/to"

遍历目录

go
func walkDir(dir string) error {
    return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        if info.IsDir() {
            fmt.Println("Directory:", path)
        } else {
            fmt.Println("File:", path)
        }
        return nil
    })
}

临时文件和目录

go
// 创建临时文件
// 使用 os.CreateTemp 在系统默认临时目录创建临时文件
// 第一个参数""表示使用默认临时目录
// 第二个参数"example.*.txt"是文件名模式,*会被随机字符替换
// 返回的 tempFile 是 *os.File 对象,代表创建的临时文件
tempFile, err := os.CreateTemp("", "example.*.txt")
if err != nil {
    log.Fatal(err)
}
defer os.Remove(tempFile.Name())

// 创建临时目录
// 使用 os.MkdirTemp 在系统默认临时目录创建临时目录
// 第一个参数""表示使用默认临时目录
// 第二个参数"example"是目录名前缀,会自动添加随机后缀
// 返回 tempDir 是创建的临时目录的完整路径
tempDir, err := os.MkdirTemp("", "example")
if err != nil {
    log.Fatal(err)
}
defer os.RemoveAll(tempDir)

简单案例

文件操作

go
package main

import (
	"fmt"
	"os"
)

func main() {
	// 写入文件
	data := []byte("WangLei so cool!")

	// Deprecated: As of Go 1.16, this function simply calls [os.WriteFile].
	//err := ioutil.WriteFile("test.txt", data, 0644)

	err := os.WriteFile("test.txt", data, 0644)
	if err != nil {
		fmt.Println("写入文件错误:", err)
		return
	}
	fmt.Println("文件写入成功")

	// 读取文件
	// Deprecated: As of Go 1.16, this function simply calls [os.ReadFile].
	//content, err := ioutil.ReadFile("test.txt")

	content, err := os.ReadFile("test.txt")
	if err != nil {
		fmt.Println("读取文件错误:", err)
		return
	}
	fmt.Println("文件内容:", string(content))

	// 检查文件是否存在
	if _, err := os.Stat("test.txt"); os.IsNotExist(err) {
		fmt.Println("文件不存在")
	} else {
		fmt.Println("文件存在")
	}

	// 删除文件
	err = os.Remove("test.txt")
	if err != nil {
		fmt.Println("删除文件错误:", err)
		return
	}
	fmt.Println("文件删除成功")
}

目录操作

go
package main

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

func main() {
	// 创建目录
	err := os.Mkdir("testdir", 0755)
	if err != nil {
		fmt.Println("创建目录错误:", err)
		return
	}
	fmt.Println("目录创建成功")

	// 创建多级目录
	err = os.MkdirAll("testdir/subdir1/subdir2", 0755)
	if err != nil {
		fmt.Println("创建多级目录错误:", err)
		return
	}
	fmt.Println("多级目录创建成功")

	// 遍历目录
	fmt.Println("目录内容:")
	err = filepath.Walk("testdir", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		fmt.Println(path)
		return nil
	})
	if err != nil {
		fmt.Println("遍历目录错误:", err)
	}

	// 删除目录
	err = os.RemoveAll("testdir")
	if err != nil {
		fmt.Println("删除目录错误:", err)
		return
	}
	fmt.Println("目录删除成功")
}

文件复制

go
package main

import (
	"fmt"
	"io"
	"os"
)

func copyFile(src, dst string) (int64, error) {
	source, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer source.Close()

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

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

func main() {
	if len(os.Args) != 3 {
		fmt.Println("用法: filecopy <源文件> <目标文件>")
		return
	}

	src := os.Args[1]
	dst := os.Args[2]

	bytesCopied, err := copyFile(src, dst)
	if err != nil {
		fmt.Println("复制文件错误:", err)
		return
	}

	fmt.Printf("成功复制 %d 字节从 %s 到 %s\n", bytesCopied, src, dst)
}
#文件目录操作 #Os库 #Golang