How can I get a file's ctime, atime, mtime and change them

Linux

ctime

ctime is the inode or file change time. The ctime gets updated when the file attributes are changed, like changing the owner, changing the permission or moving the file to an other filesystem but will also be updated when you modify a file.

The file ctime and atime are OS dependent. For Linux, ctime is set by Linux to the current timestamp when the inode or file is changed.

Here's an example, on Linux, of implicitly changing ctime by setting atime and mtime to their original values.

package main

import (
    "fmt"
    "os"
    "syscall"
    "time"
)

func statTimes(name string) (atime, mtime, ctime time.Time, err error) {
    fi, err := os.Stat(name)
    if err != nil {
        return
    }
    mtime = fi.ModTime()
    stat := fi.Sys().(*syscall.Stat_t)
    atime = time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
    ctime = time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec))
    return
}

func main() {
    name := "stat.file"
    atime, mtime, ctime, err := statTimes(name)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(atime, mtime)
    fmt.Println(ctime)
    err = os.Chtimes(name, atime, mtime)
    if err != nil {
        fmt.Println(err)
        return
    }
    atime, mtime, ctime, err = statTimes(name)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(atime, mtime)
    fmt.Println(ctime)
}

Output:

2014-01-02 02:21:26.262111165 -0500 EST 2014-01-02 02:18:13.253154086 -0500 EST
2014-01-02 02:21:25.666108207 -0500 EST
2014-01-02 02:21:26.262111165 -0500 EST 2014-01-02 02:18:13.253154086 -0500 EST
2014-01-02 02:21:43.814198198 -0500 EST

I know this is super old but I pulled together the various platform-dependent file access time structs and put them into one package with a unified API:

https://github.com/djherbis/atime

package main

import (
  "log"

  "github.com/djherbis/atime"
)

func main() {
  at, err := atime.Stat("myfile")
  if err != nil {
    log.Fatal(err.Error())
  }
  log.Println(at)
}

On a Unix system, you can get a file's mtime and ctime via syscall.Stat:

package main

import (
        "fmt"
        "log"
        "syscall"
)

func main() {
        var st syscall.Stat_t
        if err := syscall.Stat("/tmp/sysstat.go", &st); err != nil {
                log.Fatal(err)
        }
        fmt.Printf("mtime: %d\n", st.Mtimespec.Sec)
        fmt.Printf("ctime: %d\n", st.Ctimespec.Sec)
}

To update these values, you should be able to use syscall.Utimes.

Tags:

File

Go