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
|
|
|
|
|
}
|