You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

233 lines
4.3 KiB

package util
import (
"bufio"
"fmt"
"io"
"log"
"os"
"path"
"path/filepath"
"runtime"
"strings"
)
// 判断所给路径文件/文件夹是否存在
func Exists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsExist(err) {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
// FindFile 查找指定名称的文件
// 从构建后可执行文件所在目录或源码所在目录查找
func FindFile(filename string) (string, error) {
if Exists(filename) {
return filename, nil
}
// 构建后的可执行文件所在目录
execDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
return "", err
}
if file := recursiveFind(execDir, filename); len(file) > 0 {
return file, nil
}
// 源代码运行时当前文件所在目录或项目根目录
srcDir, err := os.Getwd()
if err != nil {
return "", err
}
if file := recursiveFind(srcDir, filename); len(file) > 0 {
return file, nil
}
var i int
for {
//当前行所在文件路径(从当前 util 文件开始逐层递归调用栈查找)
if _, fn, _, ok := runtime.Caller(i); ok {
if file := recursiveFind(path.Dir(fn), filename); len(file) > 0 {
return file, nil
}
} else {
break
}
i++
}
return "", nil
}
func CreateFilePath(filePath string) error {
fi, err := os.Stat(filePath)
if err == nil && fi.IsDir() {
return fmt.Errorf("%s is not file", filePath)
}
if err != nil {
if os.IsNotExist(err) {
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return err
}
} else {
return err
}
}
return nil
}
// 从指定目录查找文件,若指定目录未找到对应文件,则递归从上级目录继续查找。
func recursiveFind(dir, filename string) string {
file := path.Join(dir, filename)
if Exists(file) {
return file
}
// 已经递归到根目录了,且未找到对应文件,则返回空
if dir == filepath.Base(dir) ||
dir == filepath.Join(filepath.VolumeName(dir), filepath.Base(dir)) {
return ""
}
// 未到根目录,继续从上级目录查找
return recursiveFind(filepath.Dir(dir), filename)
}
// 判断所给路径是否为文件夹
func IsDir(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}
// 判断所给路径是否为文件
func IsFile(path string) bool {
return !IsDir(path)
}
func JoinFilePath(path ...string) string {
s := ""
for _, p := range path {
if strings.TrimSpace(p) == "" {
continue
}
if strings.HasSuffix(p, "/") {
s += p
} else {
s += p + "/"
}
}
s = strings.Replace(strings.TrimSuffix(s, "/"), "/", string(os.PathSeparator), -1)
s = strings.Replace(s, "\\", string(os.PathSeparator), -1)
return s
}
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer func() {
if err := src.Close(); err != nil {
fmt.Println(err)
}
}()
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return
}
defer func() {
if err := dst.Close(); err != nil {
fmt.Println(err)
}
}()
return io.Copy(dst, src)
}
func WriteString(filename string, data string, append, newLine bool) error {
return WriteByte(filename, []byte(data), append, newLine)
}
func WriteByte(filename string, data []byte, append, newLine bool) error {
flag := os.O_RDWR | os.O_CREATE | os.O_SYNC
perm := os.ModePerm
if append {
flag = flag | os.O_APPEND
perm = os.ModeAppend
} else {
flag = flag | os.O_TRUNC
}
f, err := os.OpenFile(filename, flag, perm)
if err != nil {
return err
}
defer func() {
if err := f.Close(); err != nil {
log.Println(err)
}
}()
//return writeFile(f, data, append, newLine)
return writeBufIO(f, data, append, newLine)
}
// 性能较低
func writeFile(file *os.File, data []byte, append, newLine bool) error {
if append && newLine {
if _, err := file.WriteString("\n"); err != nil {
return err
}
}
if _, err := file.Write(data); err != nil {
return err
}
return nil
}
func writeBufIO(file *os.File, data []byte, append, newLine bool) error {
writer := bufio.NewWriter(file)
if append && newLine {
if _, err := writer.WriteString("\n"); err != nil {
return err
}
}
if _, err := writer.Write(data); err != nil {
return err
}
return writer.Flush()
}