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