serialize/file.go

313 lines
7.5 KiB
Go

// Package serialize ...
//
// Description : 文件读写相关工具
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-04-26 6:00 下午
package serialize
import (
"encoding/xml"
"errors"
"git.zhangdeman.cn/zhangdeman/consts"
"io"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
"git.zhangdeman.cn/zhangdeman/util/define"
"github.com/go-ini/ini"
)
var (
// File ...
File *file
)
func init() {
File = &file{}
}
// file 文件相关操作
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:08 2022/5/14
type file struct {
}
// GetProjectPath 获取项目路径(可执行文件所在目录)
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:32 下午 2021/4/26
func (f *file) GetProjectPath() (string, error) {
rootPath, err := os.Getwd()
if nil != err {
return "", err
}
pathArr := strings.Split(rootPath, string(filepath.Separator))
if len(pathArr) > 0 {
if pathArr[len(pathArr)-1] == "test" {
rootPath = strings.Join(pathArr[0:len(pathArr)-1], "/")
}
}
return rootPath, nil
}
// ReadYmlContent 读取yml配置问价,并解析到指定的结构体中
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:35 下午 2021/4/26
func (f *file) ReadYmlContent(filePath string, result any) error {
if nil == result {
return errors.New("接收读取结果的数据指针为NIL")
}
var (
fileContent []byte
err error
)
if fileContent, err = f.ReadFileContent(filePath); nil != err {
return err
}
return Yml.UnmarshalWithNumber(fileContent, result)
}
// ReadJSONContent 读取JSON内容,并解析到指定的结构体中
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:23 2022/6/9
func (f *file) ReadJSONContent(filePath string, result any) error {
if nil == result {
return errors.New("接收读取结果的数据指针为NIL")
}
var (
fileContent []byte
err error
)
if fileContent, err = f.ReadFileContent(filePath); nil != err {
return err
}
return JSON.UnmarshalWithNumber(fileContent, result)
}
// ReadIniContent 读取并解析ini文件
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 13:21 2022/7/2
func (f *file) ReadIniContent(filePath string, result any) error {
if nil == result {
return errors.New("接收读取结果的数据指针为NIL")
}
return ini.MapTo(result, filePath)
}
// ReadTomlContent 读取toml格式文件
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 21:08 2023/7/31
func (f *file) ReadTomlContent(filePath string, result any) error {
if nil == result {
return errors.New("接收读取结果的数据指针为NIL")
}
if _, err := toml.DecodeFile(filePath, result); err != nil {
return err
}
return nil
}
// ReadXmlContent ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 18:39 2024/10/23
func (f *file) ReadXmlContent(filePath string, result any) error {
var (
fileContent []byte
err error
)
if fileContent, err = f.ReadFileContent(filePath); nil != err {
return err
}
return xml.Unmarshal(fileContent, result)
}
// ReadAnyFileContent 读取任意类型的文件并解析
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 13:11 2022/7/2
func (f *file) ReadAnyFileContent(filePath string, receiver any) error {
var (
parseFunc func(filePath string, receiver any) error
)
filePathArr := strings.Split(filePath, "#@#")
fileExt := ""
filePath = filePathArr[0]
if len(filePathArr) == 2 && len(filePathArr[1]) > 0 {
fileExt = strings.ToLower(filePathArr[1])
} else {
fileExt = strings.ToLower(path.Ext(filePath))
}
switch fileExt {
case consts.FileTypeJson:
parseFunc = f.ReadJSONContent
case consts.FileTypeYml, consts.FileTypeYaml:
parseFunc = f.ReadYmlContent
case consts.FileTypeIni:
parseFunc = f.ReadIniContent
case consts.FileTypeToml:
parseFunc = f.ReadTomlContent
case consts.FileTypeXml:
parseFunc = f.ReadXmlContent
default:
return errors.New(fileExt + " 暂不支持当前格式的文件解析")
}
return parseFunc(filePath, receiver)
}
// ReadFileContent 读取文件内容
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:37 下午 2021/4/26
func (f *file) ReadFileContent(filePath string) ([]byte, error) {
if exist, isFile := f.IsFileExist(filePath); !exist || !isFile {
//文件不存在或者是一个目录
return nil, errors.New(filePath + " 文件不存在或者是一个目录!")
}
//打开文件
var (
fileHandler *os.File
err error
)
if fileHandler, err = os.Open(filePath); nil != err {
return nil, err
}
defer func() {
if nil != fileHandler {
// 关闭资源
_ = fileHandler.Close()
}
}()
return io.ReadAll(fileHandler)
}
// IsFileExist 判断文件是否存在
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:37 下午 2021/4/26
func (f *file) IsFileExist(filePath string) (bool, bool) {
fileStat, err := os.Stat(filePath)
isFileExist := nil == err || os.IsExist(err)
return isFileExist, isFileExist && !fileStat.IsDir()
}
// GetFileMIMEType 获取本地文件的MIME类型
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:15 2023/2/7
func (f *file) GetFileMIMEType(filePath string) (string, error) {
var (
err error
fileHandler *os.File
)
if fileHandler, err = os.Open(filePath); nil != err {
return "", err
}
// 只需要前 512 个字节就可以了
buffer := make([]byte, 512)
if _, err = fileHandler.Read(buffer); nil != err {
return "", err
}
contentType := http.DetectContentType(buffer)
return contentType, nil
}
// ReadDirFileList 读取目录下的文件列表, 支持递归
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:42 2023/7/31
func (f *file) ReadDirFileList(dirPath string, ignoreHiddenFile bool, isRecurve bool) ([]*define.FileInfo, error) {
var (
err error
fileList []os.DirEntry
itemFileInfo os.FileInfo
)
result := make([]*define.FileInfo, 0)
if fileList, err = os.ReadDir(dirPath); nil != err {
return result, err
}
for _, itemFile := range fileList {
if ignoreHiddenFile && strings.HasPrefix(itemFile.Name(), ".") {
// 或略隐藏文件、文件夹
continue
}
if itemFileInfo, err = itemFile.Info(); nil != err {
return result, err
}
fileInfo := &define.FileInfo{
IsDir: itemFile.IsDir(),
Name: itemFile.Name(),
AbsolutePath: filepath.Join(dirPath, itemFile.Name()),
Format: "",
Size: itemFileInfo.Size(),
ModifyTime: itemFileInfo.ModTime().Unix(),
Mode: itemFileInfo.Mode(),
FileList: make([]*define.FileInfo, 0),
}
if !fileInfo.IsDir {
fileArr := strings.Split(fileInfo.Name, ".")
if len(fileArr) >= 2 {
fileInfo.Format = fileArr[len(fileArr)-1]
} else {
fileInfo.Format = "unknown"
}
} else {
fileInfo.Format = "dir"
}
fileInfo.Format = strings.ToLower(fileInfo.Format)
if fileInfo.IsDir && isRecurve {
if fileInfo.FileList, err = f.ReadDirFileList(fileInfo.AbsolutePath, ignoreHiddenFile, isRecurve); nil != err {
return result, err
}
}
result = append(result, fileInfo)
}
return result, nil
}
// ReadFileListRecurve 递归读取文件内容
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:26 2023/7/31
func (f *file) ReadFileListRecurve(rootDir string) ([]*define.FileInfo, error) {
return nil, nil
}
// FileExt 获取文件后缀
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:53 2024/6/18
func (f *file) FileExt(filePath string) string {
return strings.TrimLeft(filepath.Ext(filePath), ".")
}