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