package gio import ( "crypto/md5" "encoding/hex" "golang.org/x/sys/windows" "io" "os" "path/filepath" "runtime" "syscall" "time" ) const () type File struct { //文件名(包含后缀) Name string //文件大小 Size int64 //创建时间 CreateTime time.Time //文件后缀 Ext string //完整路径 Path string //IsOnlyRead bool //修改时间 ModifyTime time.Time //文件是否被隐藏(window) IsHidden bool IsCanRead bool IsCanWrite bool } // SetHiddenAtt 设置隐藏属性 func (f *File) SetHiddenAtt(ishidden bool) error { return setFileHiddenAtt(f.Path, ishidden) } // ToHash 获取哈希值 func (f *File) ToHash() (string, error) { ff, err := os.OpenFile(f.Path, os.O_RDONLY, os.ModePerm) if err != nil { return "", err } defer func(f *os.File) { _ = f.Close() }(ff) hash := md5.New() if _, err := io.Copy(hash, ff); err != nil { return "", err } return hex.EncodeToString(hash.Sum(nil)), nil } // Content 获取内容,返回[]byte指针则修改源文件内容 func (f *File) Content(fn func(bs []byte) *[]byte) error { ff, err := os.OpenFile(f.Path, os.O_RDONLY|os.O_WRONLY, os.ModePerm) if err != nil { return err } defer func(f *os.File) { _ = f.Close() }(ff) buffer, err := os.ReadFile(f.Path) nbs := fn(buffer) if nbs != nil { // 清空文件内容 _ = ff.Truncate(0) _, _ = ff.Seek(0, 0) // 写入新内容 _, err := ff.Write(*nbs) return err } return nil } // Delete 删除文件 func (f *File) Delete() error { err := os.Remove(f.Path) return err } // isFileHidden 判断文件是否被隐藏(windnow) func isFileHidden(path string) (bool, error) { pathPtr, err := syscall.UTF16PtrFromString(path) if err != nil { return false, err } attributes, err := windows.GetFileAttributes(pathPtr) if err != nil { return false, err } return attributes&windows.FILE_ATTRIBUTE_HIDDEN == windows.FILE_ATTRIBUTE_HIDDEN, nil } // setFileHiddenAtt 设置文件隐藏属性 func setFileHiddenAtt(path string, ishidden bool) error { pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return err } if ishidden { // 应用新的文件属性 return windows.SetFileAttributes(pathp, windows.FILE_ATTRIBUTE_HIDDEN) } else { return windows.SetFileAttributes(pathp, windows.FILE_ATTRIBUTE_NORMAL) } } // OpenFile 打开文件 返回文件以及错误信息 func OpenFile(path string) (*File, error) { f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) if err != nil { return nil, err } defer func(f *os.File) { _ = f.Close() }(f) fileinfo, err := f.Stat() if err != nil { return nil, err } var createTime int64 var modifyTime int64 ishidden := false if runtime.GOOS == "windows" { //获取文件信息 winFileAttr := fileinfo.Sys().(*syscall.Win32FileAttributeData) createTime = winFileAttr.CreationTime.Nanoseconds() / 1e9 modifyTime = winFileAttr.LastWriteTime.Nanoseconds() / 1e9 t, _ := isFileHidden(path) if t { ishidden = true } } else if runtime.GOOS == "linux" { } //ti := time.Now() //fmt.Println(ti) loc, _ := time.LoadLocation("Asia/Shanghai") tf := File{Name: f.Name(), Size: fileinfo.Size(), CreateTime: time.Unix(createTime, 0).In(loc), ModifyTime: time.Unix(modifyTime, 0).In(loc), Path: path, Ext: filepath.Ext(path), IsHidden: ishidden, } mode := fileinfo.Mode() if mode&0400 == 0400 { tf.IsCanRead = true } else { tf.IsCanRead = false } if mode&0200 == 0200 { tf.IsCanWrite = true } else { tf.IsCanWrite = false } return &tf, nil }