// Package command ... // // Description : 文件相关操作 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-05-22 12:23 package command import ( "bytes" "encoding/json" "errors" "io" "os" "strings" "gopkg.in/yaml.v2" ) // File ... // // Author : go_developer@163.com<白茶清欢> // // Date : 12:25 2022/5/22 func File(workDir string, filePath string) *fileOperate { if len(workDir) == 0 { workDir, _ = os.Getwd() } if !strings.HasPrefix(filePath, "/") { filePath = strings.ReplaceAll(workDir+"/"+filePath, "//", "/") } return &fileOperate{ workDir: workDir, filePath: filePath, permission: 0644, openFlag: os.O_RDWR, // 默认以读写模式打开 } } // file ... // // Author : go_developer@163.com<白茶清欢> // // Date : 12:24 2022/5/22 type fileOperate struct { workDir string filePath string autoCreate bool permission os.FileMode openFlag int fileHandler *os.File clearHasContent bool // 文件写入时, 清空现有内容(覆盖写入), 默认追加写入 } // IsExist 文件是否存在 // // Author : go_developer@163.com<白茶清欢> // // Date : 12:30 2022/5/22 func (f *fileOperate) IsExist() (bool, bool, error) { fileState, err := os.Stat(f.filePath) if err != nil { if os.IsNotExist(err) { return false, false, nil } return false, false, err } return true, fileState.IsDir(), nil } // AutoCreate 文件不存在时自动创建 // // Author : go_developer@163.com<白茶清欢> // // Date : 12:28 2022/5/22 func (f *fileOperate) AutoCreate() *fileOperate { f.autoCreate = true f.openFlag = f.openFlag | os.O_CREATE return f } // Permission 设置文件权限 // // Author : go_developer@163.com<白茶清欢> // // Date : 13:00 2022/5/22 func (f *fileOperate) Permission(fileModel os.FileMode) *fileOperate { f.permission = fileModel return f } // SetOpenFlag ... // // Author : go_developer@163.com<白茶清欢> // // Date : 13:40 2022/5/22 func (f *fileOperate) SetOpenFlag(flagList ...int) *fileOperate { for _, flag := range flagList { if flag == os.O_CREATE { f.AutoCreate() continue } f.openFlag = f.openFlag | flag } return f } // SetClearHasContentForWrite 设置覆盖写入文件内容 // // Author : go_developer@163.com<白茶清欢> // // Date : 16:41 2022/5/22 func (f *fileOperate) SetClearHasContentForWrite() *fileOperate { f.clearHasContent = true f.openFlag = f.openFlag | os.O_TRUNC return f } // Create 创建文件 // // Author : go_developer@163.com<白茶清欢> // // Date : 13:04 2022/5/22 func (f *fileOperate) Create() error { var ( fileExist bool isDir bool err error ) if fileExist, isDir, err = f.IsExist(); nil != err { return err } if isDir { return errors.New("路径已存在, 且为目录 : " + f.filePath) } if !fileExist { // 文件不存在 if !f.autoCreate { return errors.New("文件不存在, 且不允许自动创建 : " + f.filePath) } } f.fileHandler, err = os.OpenFile(f.filePath, f.openFlag, f.permission) return err } // Open 打开文件 // // Author : go_developer@163.com<白茶清欢> // // Date : 13:22 2022/5/22 func (f *fileOperate) Open() error { return f.Create() } // GetFileHandler 获取文件处理句柄 // // Author : go_developer@163.com<白茶清欢> // // Date : 13:23 2022/5/22 func (f *fileOperate) GetFileHandler() *os.File { return f.fileHandler } // Read 读取文件内容 // // Author : go_developer@163.com<白茶清欢> // // Date : 15:39 2022/5/22 func (f *fileOperate) Read() ([]byte, error) { if nil == f.fileHandler { if err := f.Open(); nil != err { return nil, errors.New("文件打开失败 : " + err.Error()) } } return io.ReadAll(f.fileHandler) } // ReadForJSON 读取文件, 并解析为json // // Author : go_developer@163.com<白茶清欢> // // Date : 15:40 2022/5/22 func (f *fileOperate) ReadForJSON(receiver interface{}) error { var ( content []byte err error ) if content, err = f.Read(); nil != err { return err } decoder := json.NewDecoder(bytes.NewReader(content)) decoder.UseNumber() return decoder.Decode(receiver) } // ReadForYaml 读取yaml文件, 并解析到结构体 // // Author : go_developer@163.com<白茶清欢> // // Date : 15:43 2022/5/22 func (f *fileOperate) ReadForYaml(receiver interface{}) error { var ( content []byte err error ) if content, err = f.Read(); nil != err { return err } decoder := yaml.NewDecoder(bytes.NewReader(content)) decoder.SetStrict(true) return decoder.Decode(receiver) } // Write 想文件写入内容 // // Author : go_developer@163.com<白茶清欢> // // Date : 15:47 2022/5/22 func (f *fileOperate) Write(content []byte) error { if nil == f.fileHandler { if err := f.Open(); nil != err { return errors.New("文件打开失败 : " + err.Error()) } } if f.clearHasContent { // 覆盖写入 if err := os.Truncate(f.filePath, 0); nil != err { return err } n, _ := f.fileHandler.Seek(0, io.SeekEnd) _, writeErr := f.fileHandler.WriteAt(content, n) return writeErr } // 追加写入 _, writeErr := f.fileHandler.Write(content) return writeErr }