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