In Go language, obtaining detailed information about files or folders is one of the fundamental tasks in file system operations. By using the standard libraries os and io/fs, you can easily access file metadata, such as size, modification time, permissions, etc.

Using os.Stat to Get File Information

The os.Stat function returns a FileInfo interface, which provides basic information about a file or folder. The following example shows how to obtain detailed information about a file.

package main

import (
    "fmt"
    "os"
)

func main() {
    info, err := os.Stat("example.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Name:", info.Name())
    fmt.Println("Size:", info.Size(), "bytes")
    fmt.Println("Mode:", info.Mode())
    fmt.Println("ModTime:", info.ModTime())
    fmt.Println("IsDir:", info.IsDir())
}

Tip: If the file does not exist, os.Stat will return an error, so be sure to check error handling.

Methods of the FileInfo Interface

The FileInfo interface defines multiple methods to retrieve file attributes. The table below lists common methods and their descriptions.

Method Description Example Output
Name() Returns the name of the file or folder example.txt
Size() Returns the file size (in bytes) 1024
Mode() Returns the file permission mode -rw-r--r--
ModTime() Returns the last modification time 2023-10-01 12:00:00
IsDir() Returns whether it is a folder false

Traversing Folder Contents

To obtain detailed information for all files in a folder, you can use os.ReadDir or filepath.Walk. The following example uses os.ReadDir to list entries in a folder.

package main

import (
    "fmt"
    "os"
)

func main() {
    entries, err := os.ReadDir(".")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    for _, entry := range entries {
        info, err := entry.Info()
        if err != nil {
            fmt.Println("Error getting info for", entry.Name(), ":", err)
            continue
        }
        fmt.Printf("Name: %s, Size: %d bytes, IsDir: %v\n", info.Name(), info.Size(), info.IsDir())
    }
}

Note: os.ReadDir was introduced in Go 1.16, and it is more efficient than ioutil.ReadDir, so it is recommended to use.

Using filepath.Walk for Recursive Traversal

For cases that require recursively traversing an entire directory tree, filepath.Walk is a powerful tool. The following example shows how to traverse a folder and print the path and size of each file.

package main

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

func main() {
    err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }
        fmt.Printf("Path: %s, Size: %d bytes\n", path, info.Size())
        return nil
    })
    if err != nil {
        fmt.Println("Error:", err)
    }
}

Getting Symbolic Link Information

If a file is a symbolic link, os.Stat will return information about the target file the link points to. To get information about the link itself, you can use os.Lstat. The following example demonstrates this.

package main

import (
    "fmt"
    "os"
)

func main() {
    // Assume there is a symbolic link link.txt pointing to example.txt
    info, err := os.Lstat("link.txt")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Is symbolic link:", info.Mode() & os.ModeSymlink != 0)
    fmt.Println("Link info:", info)
}