command/file.go

252 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package command ...
//
// Description : 文件相关操作
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2022-05-22 12:23
package command
import (
"bytes"
"encoding/json"
"errors"
"io"
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
// 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)
}
}
// 创建目录
fileArr := strings.Split(f.filePath, string(filepath.Separator))
if len(fileArr) >= 2 {
pathStr := strings.Join(fileArr[0:len(fileArr)-1], string(filepath.Separator))
if err = os.MkdirAll(pathStr, 0777); nil != err {
return errors.New("文件目录创建失败 : " + err.Error())
}
}
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))
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
}