事情是这样的,在一个项目中,我需要读取系统中的某个文件的创建时间,根据时间做不同的处理,如超过一定时间后就删除掉。查询了一下,获取文件创建时间可以使用标准库中的os 和 syscall 来完成,但是syscall该库在不同的系统中的接口是不一样的,如在Mac下是这样使用的
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
f, _ := os.Stat("1.txt")
fattr, _ := f.Sys().(*syscall.Stat_t)
fmt.Println(fattr.Ctimespec.Sec)
}
func (fs.FileInfo).Sys() interface{}*syscall.Stat_t*syscall.Win32FileAttributeData
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
f, _ := os.Stat("1.txt")
fattr, _ := f.Sys().(*syscall.Stat_t)
fmt.Println(fattr.Ctime.Sec )
}
在windows中又是下面的这样
package main
import (
"fmt"
"os"
"syscall"
)
func main() {
f, _ := os.Stat("1.txt")
fattr, _ := f.Sys().(*syscall.Win32FileAttributeData)
fmt.Println(fattr.CreationTime.Nanoseconds()/1e9)
}
如果要画一个图表示大概是下面这个样子
上面的其实还不是麻烦的,如果你是在Mac上开发的,将来你的程序如果要在windows上运行的话,那么开发的时候写上适合windows的代码,就会在ide上直接报错了,也无法直接编译。
GOOS=windows GOARCH=amd64 go build main.go
GOOS=linux GOARCH=amd64 go build main.go
//go:build
//go:build darwin
package main
import (
"errors"
"os"
"syscall"
)
func GetCtime(path string) (int64, error) {
finfo, err := os.Stat(path)
if err != nil {
return 0, err
}
fattr, ok := finfo.Sys().(*syscall.Stat_t)
if !ok {
return 0, errors.New("获取文件属性失败")
}
return fattr.Ctimespec.Sec, nil
}
//go:build darwin
//go:build linux
package main
//go:build windows
package main
go:build 的逻辑关系
go:build 标签可以有逻辑关系的,有且(AND),或(OR)非(NOT),比如我想要设置某个文件在darwin或liunx系统时编译,可以使用
//go:build darwin || linux
也可以是且(AND)和或(OR)的关系混合
//go:build (darwin && amd64) || linux
自定义标签
除了GOOS和GOARCH,我们也可以自定义一些标签,如dev,release
//go:build dev
go build -tags "dev" .