Is there any way to set just the mtime
on a file with os.Chtimes
? I thought I could pass a modified mtime
along with an unmodified atime
to Chtimes
, but the FileInfo
returned by os.Stat
only gives you mtime
, via os.FileInfo.ModTime()
.
It seems odd that os.Chtimes
requires changing both atime
and mtime
at once, but there is no way to retrieve atime
from the provided os
functions.
this is related to How can I get a file's ctime,atime,mtime and change them using Golang? , but I'd like to set less information.
This allows you to modify mtime
.
package main
import (
"fmt"
"os"
"syscall"
"time"
)
func main() {
name := "main"
atime, mtime, ctime, err := statTimes(name)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(atime, mtime, ctime)
// new mtime
newMtime := time.Date(2000, time.February, 1, 3, 4, 5, 0, time.UTC)
// set new mtime
err = os.Chtimes(name, atime, newMtime)
if err != nil {
fmt.Println(err)
return
}
atime, mtime, ctime, err = statTimes(name)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(atime, mtime, ctime)
}
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
}
and get atime, ctime from fi.Sys().(*syscall.Stat_t)
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))
I know that the file systems of various operating systems are different. Commonly used parts are defined in os.Fileinfo as below. https://golang.org/search?q=os.FileInfo
// A FileInfo describes a file and is returned by Stat and Lstat.
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() interface{} // underlying data source (can return nil)
}
A fileStat is the implementation of FileInfo. The fileStat is declared differently for each os. https://golang.org/search?q=fileStat
linux, unix actually uses the following struct.
// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
type fileStat struct {
name string
size int64
mode FileMode
modTime time.Time
sys syscall.Stat_t
}
and Obtain ctime and atime from syscall.Stat_t.