TOC

Golang: 目录与文件操作汇总

Golang os 中有很多文件系统相关的操作。

创建文件

// *os.File
file, err = os.Create("abc.txt")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

删除文件

os.Remove()

读写文件

// ioutil
func ReadFile(filename string) ([]byte, error)
func WriteFile(filename string, data []byte, perm os.FileMode) error

// os
func Open(name string) (*File, error)
func OpenFile(name string, flag int, perm FileMode) (*File, error)
func ReadFileToString(filename string) ([]string, error) {
    file, err := os.Open(filename)
    if err != nil {
        return nil, err
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)

    var data []string

    for scanner.Scan() {
        line := scanner.Text()
        data = append(data, line)
    }
    if err = scanner.Err(); err != nil {
        return nil, err
    }

    return data, nil
}

// 写

// 如果文件大于指定大小,则截断到指定大小
// 如果文件小于指定大小,则填充到指定大小
file, err := os.Truncate("abc.txt", 1024)
if err != nil {
    log.Fatal(err)
}

裁剪文件(Truncate)

file, err := os.OpenFile("abc.txt", os.O_RDWR, 0644)
if err != nil {
    log.Fatal(err)
}
defer file.Close()

err := file.Truncate(1024)
if err != nil {
    log.Fatal(err)
}
// os.Truncate(path string, size int64) error
err := os.Truncate("abc.txt", 1024)
if err != nil {
    fmt.Println("截断文件失败:", err)
}

创建目录(mkdir)

err := os.Mkdir(dirName, 0755) // 不能创建已经存在的目录
// err := os.MkdirAll(dirPath, 0755) // mkdir -p
if err != nil {
    fmt.Println("创建目录失败:", err)
    return
}

删除目录(rm)

err := os.Remove(dirName) // 不能删除非空目录
// err := os.RemoveAll(dirName) // rm -rf
if err != nil {
    fmt.Println("删除目录失败:", err)
    return
}

查看目录(List/Walk)

dirEntries, err := os.ReadDir(dirPath)
if err != nil {
    return err
}
for _, entry := range dirEntries {
    entryPath := filepath.Join(dirPath, entry.Name())
    if entry.IsDir() {
        fmt.Println("目录:", entryPath)
    } else {
        fmt.Println("文件:", entryPath)
    }
}
package main

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

func visit(path string, info os.FileInfo, err error) error {
    if err != nil {
        fmt.Println("访问目录失败:", err)
        return nil
    }
    if info.IsDir() {
        fmt.Println("目录:", path)
    } else {
        fmt.Println("文件:", path)
    }
    return nil
}

func main() {
    dirPath := "/path/to/directory"
    err := filepath.Walk(dirPath, visit)
    if err != nil {
        fmt.Println("遍历目录失败:", err)
        return
    }
}

查看文件信息(Stat)

fp.Stat()  // 句柄上执行 Stat 方法

fi, err = os.Stat(filepath)
// type FileInfo interface {
//  Name() string       // base name of the file
//  Size() int64        // length in bytes for regular files; system-dependent for others
//  Mode() FileMode     // file mode bits
//  ModTime() time.Time // modification time
//  IsDir() bool        // abbreviation for Mode().IsDir()
//  Sys() any           // underlying data source (can return nil)
// }

// FileMode -> fs.FileMode -> type FileMode uint32
// func (m FileMode) IsDir() bool
// func (m FileMode) IsRegular() bool
// func (m FileMode) Perm() FileMode
// func (m FileMode) String() string
// func (m FileMode) Type() FileMode
// const (
//  // The single letters are the abbreviations
//  // used by the String method's formatting.
//  ModeDir        FileMode = 1 << (32 - 1 - iota) // d: is a directory
//  ModeAppend                                     // a: append-only
//  ModeExclusive                                  // l: exclusive use
//  ModeTemporary                                  // T: temporary file; Plan 9 only
//  ModeSymlink                                    // L: symbolic link
//  ModeDevice                                     // D: device file
//  ModeNamedPipe                                  // p: named pipe (FIFO)
//  ModeSocket                                     // S: Unix domain socket
//  ModeSetuid                                     // u: setuid
//  ModeSetgid                                     // g: setgid
//  ModeCharDevice                                 // c: Unix character device, when ModeDevice is set
//  ModeSticky                                     // t: sticky
//  ModeIrregular                                  // ?: non-regular file; nothing else is known about this file

//  // Mask for the type bits. For regular files, none will be set.
//  ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular

//  ModePerm FileMode = 0777 // Unix permission bits
// )

// is exists
func IsNotExist(err error) bool
// 注意:这个方法只有在出现异常,并且异常是路径已存在导致的,才会返回 True
func IsExist(err error) bool

// is dir
if fi.IsDir() {
    ...
}

// is file
if fi.Mode().IsRegular() {
    ...
}

// readable

// writable

// executable

移动文件

os.Rename(src, dst)

复制文件

sourceFile, err := os.Open(sourceFilePath)
if err != nil {
    return err
}
defer sourceFile.Close()
destinationFile, err := os.Create(destinationFilePath)
if err != nil {
    return err
}
defer destinationFile.Close()
_, err = io.Copy(destinationFile, sourceFile)

创建链接

os.Link()
os.Symlink()

临时目录和临时文件

tempFile, err := os.CreateTemp("", "tmp*.txt")  // *os.File
tempFilePath := tempFile.Name()

tempDir, err := os.MkdirTemp("", "tmp") // string

权限

fp.Chmod()
fp.Chown()  // os.Getuid(), os.Getgid()
如果你有魔法,你可以看到一个评论框~