file/filetools.go

222 lines
5.5 KiB
Go
Raw Normal View History

2022-02-04 21:22:04 +05:00
package file
import (
"encoding/json"
2022-07-09 13:55:20 +05:00
"fmt"
2022-02-04 21:22:04 +05:00
"io/ioutil"
"os"
"os/user"
"path/filepath"
"strings"
2022-05-29 04:21:30 +05:00
2022-06-05 10:52:12 +05:00
"github.com/gofrs/flock"
2022-02-04 21:22:04 +05:00
)
//Получить текущую рабочую папку
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
func GetCWD() string {
wd, e := os.Getwd()
if e != nil {
return ""
}
return wd
}
//Получить имя исполняемого файла
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
func GetBinName() string {
bn, e := os.Executable()
if e != nil {
return ""
}
return filepath.Base(bn)
}
//Получить папку исполняемого файла
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
func GetBinDir() string {
bn, e := os.Executable()
if e != nil {
return ""
}
return filepath.Dir(bn)
}
//Получить домашнюю папку
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
func GetHome() string {
u, e := user.Current()
if e != nil {
return ""
}
return u.HomeDir
}
//Развернуть путь до полного
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
//Префиксы:
// "." - заменяется папкой исполняемого файла
// "~" - заменяется домашней папкой пользователя
// "/" - замен не производится
// "" - дополняется текущей рабочей папкой
func RealPath(path string) string {
if len(path) < 1 {
return GetCWD()
}
switch path[0] {
case '.':
return GetBinDir() + "/" + strings.TrimLeft(path, "./")
case '~':
return GetHome() + "/" + strings.TrimLeft(path, "~/")
case '/':
return path
default:
return GetCWD() + "/" + path
}
}
//Получить расширение файла
2022-05-31 08:01:49 +05:00
// 0.1.1
2022-02-04 21:22:04 +05:00
func Ext(file string) string {
2022-05-29 04:21:30 +05:00
fpa := strings.Split(file, "/")
fa := strings.Split(fpa[len(fpa)-1], ".")
2022-02-04 21:22:04 +05:00
if len(fa) < 2 {
return ""
}
return fa[len(fa)-1]
}
//Существует ли файл
2022-05-31 08:01:49 +05:00
// 0.1.0
2022-02-04 21:22:04 +05:00
func Exists(file string) bool {
if _, e := os.Stat(RealPath(file)); os.IsNotExist(e) {
return false
}
return true
}
//Загрузить файл
2022-07-09 13:55:20 +05:00
// 0.2.0
func Load(file string) ([]byte, error) {
2022-02-04 21:22:04 +05:00
if !Exists(file) {
2022-07-09 13:55:20 +05:00
//return nil, errs.RaiseError(ErrFileNotFound, "File '"+file+"' not found")
return nil, fmt.Errorf("file not found: %s", file)
2022-02-04 21:22:04 +05:00
}
ret, e := ioutil.ReadFile(RealPath(file))
if e != nil {
2022-07-09 13:55:20 +05:00
//return nil, errs.RaiseError(ErrFileRead, "Error read file '"+file+"': "+e.Error())
return nil, fmt.Errorf("error read file '%s': %v", file, e)
2022-02-04 21:22:04 +05:00
}
return ret, nil
}
//Загрузить и распарсить JSON-файл
2022-07-09 13:55:20 +05:00
// 0.2.0
func LoadJSON(file string) (data interface{}, err error) {
2022-05-29 04:21:30 +05:00
src, err := Load(file)
if err != nil {
2022-07-09 13:55:20 +05:00
return nil, err
2022-02-04 21:22:04 +05:00
}
2022-05-29 04:21:30 +05:00
e := json.Unmarshal(src, &data)
2022-02-04 21:22:04 +05:00
if e != nil {
2022-07-09 13:55:20 +05:00
//return nil, errs.RaiseError(ErrParseJSON, "Error parse file '"+file+"': "+e.Error())
return nil, fmt.Errorf("error parse file '%s': %v", file, e)
2022-02-04 21:22:04 +05:00
}
return
}
2022-06-05 10:52:12 +05:00
//Сохранить файл, создать путь если не существует
2022-07-09 13:55:20 +05:00
// 0.2.0
func Save(file string, data []byte, perms ...os.FileMode) error {
2022-02-04 21:22:04 +05:00
fName := RealPath(file)
fPath := filepath.Dir(fName)
2022-06-05 10:52:12 +05:00
pa := getPerms(perms)
if e := os.MkdirAll(fPath, pa[1]); e != nil {
2022-07-09 13:55:20 +05:00
//return errs.RaiseError(ErrCreatePath, "Error create path '"+fPath+"': "+e.Error())
return fmt.Errorf("error create path '%s': %v", fPath, e)
2022-02-04 21:22:04 +05:00
}
2022-06-05 10:52:12 +05:00
if e := os.WriteFile(fName, data, pa[0]); e != nil {
2022-07-09 13:55:20 +05:00
//return errs.RaiseError(ErrFileWrite, "Error write file '"+fName+"': "+e.Error())
return fmt.Errorf("error write file '%s': %v", file, e)
2022-02-04 21:22:04 +05:00
}
return nil
}
2022-06-05 10:52:12 +05:00
//Разобрать массив прав
// 0.1.3
func getPerms(perms []os.FileMode) (pa []os.FileMode) {
pa = make([]os.FileMode, 0)
if len(perms) > 0 {
pa = append(pa, perms[0])
} else {
pa = append(pa, 0664)
}
if len(perms) > 1 {
pa = append(pa, perms[1])
} else {
pa = append(pa, 0775)
}
return pa
}
//Добавить в файл, создать если не существует
2022-07-09 13:55:20 +05:00
// 0.2.0
func Append(file string, data []byte, perms ...os.FileMode) error {
2022-06-05 10:52:12 +05:00
fName := RealPath(file)
f, err := OpenCreate(fName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, perms...)
if err != nil {
2022-07-09 13:55:20 +05:00
//return errs.UpError(err)
return err
2022-06-05 10:52:12 +05:00
}
defer f.Close()
lock := flock.New(fName)
if e := lock.Lock(); err != nil {
2022-07-09 13:55:20 +05:00
//return errs.RaiseError(ErrFileLock, e.Error())
return fmt.Errorf("error lock file '%s': %v", fName, e)
2022-06-05 10:52:12 +05:00
}
defer lock.Unlock()
f.Write(data)
return nil
}
2022-02-04 21:22:04 +05:00
//Сохранить JSON-файл
2022-07-09 13:55:20 +05:00
// 0.2.0
func SaveJSON(file string, data interface{}, perms ...os.FileMode) error {
2022-02-04 21:22:04 +05:00
jsonData, e := json.Marshal(data)
if e != nil {
2022-07-09 13:55:20 +05:00
//return errs.RaiseError(ErrParseJSON, "Error parse data for file '"+file+"': "+e.Error())
return fmt.Errorf("error marshal data for file '%s': %v", file, e)
2022-02-04 21:22:04 +05:00
}
2022-06-05 10:52:12 +05:00
return Save(file, jsonData, perms...)
2022-02-04 21:22:04 +05:00
}
//Удалить файл
2022-07-09 13:55:20 +05:00
// 0.2.0
func Delete(file string) error {
2022-02-04 21:22:04 +05:00
if e := os.Remove(RealPath(file)); e != nil {
2022-07-09 13:55:20 +05:00
//return errs.RaiseError(ErrFileDelete, "Error delete file '"+file+"': "+e.Error())
return fmt.Errorf("error delete file '%s': %v", RealPath(file), e)
2022-02-04 21:22:04 +05:00
}
return nil
}
2022-05-30 11:39:58 +05:00
2022-06-05 10:52:12 +05:00
//Открыть файл, создать если не существует, вместе с путем
2022-07-09 13:55:20 +05:00
// 0.2.0
func OpenCreate(file string, flag int, perms ...os.FileMode) (*os.File, error) {
2022-06-05 10:52:12 +05:00
pa := getPerms(perms)
2022-05-30 11:39:58 +05:00
fn := RealPath(file)
fp := filepath.Dir(fn)
if !Exists(fn) {
2022-06-05 10:52:12 +05:00
if e := os.MkdirAll(fp, pa[1]); e != nil {
2022-07-09 13:55:20 +05:00
//return nil, errs.RaiseError(ErrCreatePath, "Error create path: '"+fp+"': "+e.Error())
return nil, fmt.Errorf("error create path '%s': %v", fp, e)
2022-05-30 11:39:58 +05:00
}
}
2022-06-05 10:52:12 +05:00
f, e := os.OpenFile(fn, flag, pa[0])
2022-05-30 11:39:58 +05:00
if e != nil {
2022-07-09 13:55:20 +05:00
//return nil, errs.RaiseError(ErrFileOpen, "Error create file: '"+fn+"': "+e.Error())
return nil, fmt.Errorf("error create file '%s': %v", fn, e)
2022-05-30 11:39:58 +05:00
}
return f, nil
}