package mokuai import ( "archive/zip" "crypto/md5" "encoding/hex" "fmt" "io" "io/fs" "io/ioutil" "os" "path" "path/filepath" "strings" ) // 文件_文本写出 func File_WriteStr(filepath string, textstr string) bool { err := ioutil.WriteFile(filepath, []byte(textstr), 0644) if err != nil { return false } else { return true } } // 文件_字节集写出 func File_WriteByte(filepath string, dataByte []byte) bool { err := ioutil.WriteFile(filepath, dataByte, 0644) if err != nil { return false } else { return true } } // 文件_追加写入内容 func File_WriteEndStr(filepath string, textstr string) bool { f, err := os.OpenFile(filepath, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm) if err != nil { return false } _, err = f.WriteString(textstr) if err != nil { return false } _ = f.Close() return true } // 文件_文本读入,失败返回空 func File_ReadStr(filepath string) (textstr string) { fileobj, ok := ioutil.ReadFile(filepath) if ok != nil { textstr = "" } else { textstr = string(fileobj) } return } // 文件_字节集读入,失败返回 nil func File_ReadByte(filepath string) (dataByte []byte) { fileobj, ok := ioutil.ReadFile(filepath) if ok != nil { dataByte = nil } else { dataByte = fileobj } return } // 文件_删除自身 func File_Delself() bool { epath, err := os.Executable() if err != nil { panic(err) } err = os.Remove(epath) if err != nil { return false } else { return true } } // 取文件的MD5 。失败返回空 func File_HashFileMd5(filePath string) (md5Str string) { file, err := os.Open(filePath) if err != nil { md5Str = "" return } defer file.Close() hash := md5.New() if _, err = io.Copy(hash, file); err != nil { return } hashInBytes := hash.Sum(nil)[:16] md5Str = hex.EncodeToString(hashInBytes) return } // 判断所给路径是否为文件存在 true:存在 ; false:不存在 func File_IsFile(path string) bool { f, flag := File_IsExists(path) return flag && !f.IsDir() } // 判断路径是否存在 true:存在 ; false:不存在 func File_IsExists(path string) (os.FileInfo, bool) { f, err := os.Stat(path) return f, err == nil || os.IsExist(err) } // 判断所给路径是否为文件夹 true:存在 ; false:不存在 func File_IsDir(path string) bool { f, flag := File_IsExists(path) return flag && f.IsDir() } // 判断文件或文件夹是否存在 func Dir_IsExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } // 获取当前程序运行目录 func File_Get_Current_Directory() string { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { fmt.Println(err) } return strings.Replace(dir, "\\", "/", -1) } // 获取当前程序运行绝对路径(包括文件名) func File_Get_Current_Path() string { path, err := filepath.Abs(os.Args[0]) if err != nil { fmt.Println(err) } return strings.Replace(path, "\\", "/", -1) } // 获取当前程序运行名称 func File_Get_Current_Name() string { name := filepath.Base(os.Args[0]) return name } // 创建文件夹 (可以递归创建目录) func Dir_Create(dirName string) bool { err := os.MkdirAll(dirName, 0755) if err != nil { return false } else { return true } } /* 复制文件 srcFileName: 源文件路径 ; dstFileName:目标文件路径 */ func File_CopyFile(srcFileName string, dstFileName string) (ReErr string) { //打开源文件 srcFile, err := os.Open(srcFileName) if err != nil { ReErr = "源文件读取失败,原因是:" + err.Error() return } defer func() { err = srcFile.Close() if err != nil { ReErr = "源文件关闭失败,原因是:" + err.Error() return } }() //创建目标文件,稍后会向这个目标文件写入拷贝内容 distFile, err := os.Create(dstFileName) if err != nil { ReErr = "目标文件创建失败,原因是:" + err.Error() return } defer func() { err = distFile.Close() if err != nil { ReErr = "目标文件关闭失败,原因是:" + err.Error() return } }() //定义指定长度的字节切片,每次最多读取指定长度 var tmp = make([]byte, 1024*4) //循环读取并写入 for { n, err := srcFile.Read(tmp) n, _ = distFile.Write(tmp[:n]) if err != nil { if err == io.EOF { //读到了文件末尾,并且写入完毕,任务完成返回(关闭文件的操作由defer来完成) return } else { ReErr = "拷贝过程中发生错误,错误原因为:" + err.Error() return } } } } // 解压ZIP文件 // Note that the destination directory don't need to specify the trailing path separator. func File_Unzip(zipPath, dstDir string) error { // open zip file reader, err := zip.OpenReader(zipPath) if err != nil { return err } defer reader.Close() for _, file := range reader.File { if err := unzipFile(file, dstDir); err != nil { return err } } return nil } func unzipFile(file *zip.File, dstDir string) error { // create the directory of file filePath := path.Join(dstDir, file.Name) if file.FileInfo().IsDir() { if err := os.MkdirAll(filePath, os.ModePerm); err != nil { return err } return nil } if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } // open the file rc, err := file.Open() if err != nil { return err } defer rc.Close() // create the file w, err := os.Create(filePath) if err != nil { return err } defer w.Close() // save the decompressed file content _, err = io.Copy(w, rc) return err } // Zip 压缩ZIP文件. // If a path is a dir don't need to specify the trailing path separator. // For example calling Zip("archive.zip", "dir", "csv/baz.csv") will get archive.zip and the content of which is // dir // |-- foo.txt // |-- bar.txt // baz.csv func File_Zip(zipPath string, paths ...string) error { // create zip file if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil { return err } archive, err := os.Create(zipPath) if err != nil { return err } defer archive.Close() // new zip writer zipWriter := zip.NewWriter(archive) defer zipWriter.Close() // traverse the file or directory for _, srcPath := range paths { // remove the trailing path separator if path is a directory srcPath = strings.TrimSuffix(srcPath, string(os.PathSeparator)) // visit all the files or directories in the tree err = filepath.Walk(srcPath, func(path string, info fs.FileInfo, err error) error { if err != nil { return err } // create a local file header header, err := zip.FileInfoHeader(info) if err != nil { return err } // set compression header.Method = zip.Deflate // set relative path of a file as the header name header.Name, err = filepath.Rel(filepath.Dir(srcPath), path) if err != nil { return err } if info.IsDir() { header.Name += string(os.PathSeparator) } // create writer for the file header and save content of the file headerWriter, err := zipWriter.CreateHeader(header) if err != nil { return err } if info.IsDir() { return nil } f, err := os.Open(path) if err != nil { return err } defer f.Close() _, err = io.Copy(headerWriter, f) return err }) if err != nil { return err } } return nil }