handle_file.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package mokuai
  2. import (
  3. "archive/zip"
  4. "crypto/md5"
  5. "encoding/hex"
  6. "fmt"
  7. "io"
  8. "io/fs"
  9. "io/ioutil"
  10. "os"
  11. "path"
  12. "path/filepath"
  13. "strings"
  14. )
  15. // 文件_文本写出
  16. func File_WriteStr(filepath string, textstr string) bool {
  17. err := ioutil.WriteFile(filepath, []byte(textstr), 0644)
  18. if err != nil {
  19. return false
  20. } else {
  21. return true
  22. }
  23. }
  24. // 文件_字节集写出
  25. func File_WriteByte(filepath string, dataByte []byte) bool {
  26. err := ioutil.WriteFile(filepath, dataByte, 0644)
  27. if err != nil {
  28. return false
  29. } else {
  30. return true
  31. }
  32. }
  33. // 文件_追加写入内容
  34. func File_WriteEndStr(filepath string, textstr string) bool {
  35. f, err := os.OpenFile(filepath, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm)
  36. if err != nil {
  37. return false
  38. }
  39. _, err = f.WriteString(textstr)
  40. if err != nil {
  41. return false
  42. }
  43. _ = f.Close()
  44. return true
  45. }
  46. // 文件_文本读入,失败返回空
  47. func File_ReadStr(filepath string) (textstr string) {
  48. fileobj, ok := ioutil.ReadFile(filepath)
  49. if ok != nil {
  50. textstr = ""
  51. } else {
  52. textstr = string(fileobj)
  53. }
  54. return
  55. }
  56. // 文件_字节集读入,失败返回 nil
  57. func File_ReadByte(filepath string) (dataByte []byte) {
  58. fileobj, ok := ioutil.ReadFile(filepath)
  59. if ok != nil {
  60. dataByte = nil
  61. } else {
  62. dataByte = fileobj
  63. }
  64. return
  65. }
  66. // 文件_删除自身
  67. func File_Delself() bool {
  68. epath, err := os.Executable()
  69. if err != nil {
  70. panic(err)
  71. }
  72. err = os.Remove(epath)
  73. if err != nil {
  74. return false
  75. } else {
  76. return true
  77. }
  78. }
  79. // 取文件的MD5 。失败返回空
  80. func File_HashFileMd5(filePath string) (md5Str string) {
  81. file, err := os.Open(filePath)
  82. if err != nil {
  83. md5Str = ""
  84. return
  85. }
  86. defer file.Close()
  87. hash := md5.New()
  88. if _, err = io.Copy(hash, file); err != nil {
  89. return
  90. }
  91. hashInBytes := hash.Sum(nil)[:16]
  92. md5Str = hex.EncodeToString(hashInBytes)
  93. return
  94. }
  95. // 判断所给路径是否为文件存在 true:存在 ; false:不存在
  96. func File_IsFile(path string) bool {
  97. f, flag := File_IsExists(path)
  98. return flag && !f.IsDir()
  99. }
  100. // 判断路径是否存在 true:存在 ; false:不存在
  101. func File_IsExists(path string) (os.FileInfo, bool) {
  102. f, err := os.Stat(path)
  103. return f, err == nil || os.IsExist(err)
  104. }
  105. // 判断所给路径是否为文件夹 true:存在 ; false:不存在
  106. func File_IsDir(path string) bool {
  107. f, flag := File_IsExists(path)
  108. return flag && f.IsDir()
  109. }
  110. // 判断文件或文件夹是否存在
  111. func Dir_IsExists(path string) (bool, error) {
  112. _, err := os.Stat(path)
  113. if err == nil {
  114. return true, nil
  115. }
  116. if os.IsNotExist(err) {
  117. return false, nil
  118. }
  119. return false, err
  120. }
  121. // 获取当前程序运行目录
  122. func File_Get_Current_Directory() string {
  123. dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
  124. if err != nil {
  125. fmt.Println(err)
  126. }
  127. return strings.Replace(dir, "\\", "/", -1)
  128. }
  129. // 获取当前程序运行绝对路径(包括文件名)
  130. func File_Get_Current_Path() string {
  131. path, err := filepath.Abs(os.Args[0])
  132. if err != nil {
  133. fmt.Println(err)
  134. }
  135. return strings.Replace(path, "\\", "/", -1)
  136. }
  137. // 获取当前程序运行名称
  138. func File_Get_Current_Name() string {
  139. name := filepath.Base(os.Args[0])
  140. return name
  141. }
  142. // 创建文件夹 (可以递归创建目录)
  143. func Dir_Create(dirName string) bool {
  144. err := os.MkdirAll(dirName, 0755)
  145. if err != nil {
  146. return false
  147. } else {
  148. return true
  149. }
  150. }
  151. /*
  152. 复制文件
  153. srcFileName: 源文件路径 ; dstFileName:目标文件路径
  154. */
  155. func File_CopyFile(srcFileName string, dstFileName string) (ReErr string) {
  156. //打开源文件
  157. srcFile, err := os.Open(srcFileName)
  158. if err != nil {
  159. ReErr = "源文件读取失败,原因是:" + err.Error()
  160. return
  161. }
  162. defer func() {
  163. err = srcFile.Close()
  164. if err != nil {
  165. ReErr = "源文件关闭失败,原因是:" + err.Error()
  166. return
  167. }
  168. }()
  169. //创建目标文件,稍后会向这个目标文件写入拷贝内容
  170. distFile, err := os.Create(dstFileName)
  171. if err != nil {
  172. ReErr = "目标文件创建失败,原因是:" + err.Error()
  173. return
  174. }
  175. defer func() {
  176. err = distFile.Close()
  177. if err != nil {
  178. ReErr = "目标文件关闭失败,原因是:" + err.Error()
  179. return
  180. }
  181. }()
  182. //定义指定长度的字节切片,每次最多读取指定长度
  183. var tmp = make([]byte, 1024*4)
  184. //循环读取并写入
  185. for {
  186. n, err := srcFile.Read(tmp)
  187. n, _ = distFile.Write(tmp[:n])
  188. if err != nil {
  189. if err == io.EOF { //读到了文件末尾,并且写入完毕,任务完成返回(关闭文件的操作由defer来完成)
  190. return
  191. } else {
  192. ReErr = "拷贝过程中发生错误,错误原因为:" + err.Error()
  193. return
  194. }
  195. }
  196. }
  197. }
  198. // 解压ZIP文件
  199. // Note that the destination directory don't need to specify the trailing path separator.
  200. func File_Unzip(zipPath, dstDir string) error {
  201. // open zip file
  202. reader, err := zip.OpenReader(zipPath)
  203. if err != nil {
  204. return err
  205. }
  206. defer reader.Close()
  207. for _, file := range reader.File {
  208. if err := unzipFile(file, dstDir); err != nil {
  209. return err
  210. }
  211. }
  212. return nil
  213. }
  214. func unzipFile(file *zip.File, dstDir string) error {
  215. // create the directory of file
  216. filePath := path.Join(dstDir, file.Name)
  217. if file.FileInfo().IsDir() {
  218. if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
  219. return err
  220. }
  221. return nil
  222. }
  223. if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
  224. return err
  225. }
  226. // open the file
  227. rc, err := file.Open()
  228. if err != nil {
  229. return err
  230. }
  231. defer rc.Close()
  232. // create the file
  233. w, err := os.Create(filePath)
  234. if err != nil {
  235. return err
  236. }
  237. defer w.Close()
  238. // save the decompressed file content
  239. _, err = io.Copy(w, rc)
  240. return err
  241. }
  242. // Zip 压缩ZIP文件.
  243. // If a path is a dir don't need to specify the trailing path separator.
  244. // For example calling Zip("archive.zip", "dir", "csv/baz.csv") will get archive.zip and the content of which is
  245. // dir
  246. // |-- foo.txt
  247. // |-- bar.txt
  248. // baz.csv
  249. func File_Zip(zipPath string, paths ...string) error {
  250. // create zip file
  251. if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil {
  252. return err
  253. }
  254. archive, err := os.Create(zipPath)
  255. if err != nil {
  256. return err
  257. }
  258. defer archive.Close()
  259. // new zip writer
  260. zipWriter := zip.NewWriter(archive)
  261. defer zipWriter.Close()
  262. // traverse the file or directory
  263. for _, srcPath := range paths {
  264. // remove the trailing path separator if path is a directory
  265. srcPath = strings.TrimSuffix(srcPath, string(os.PathSeparator))
  266. // visit all the files or directories in the tree
  267. err = filepath.Walk(srcPath, func(path string, info fs.FileInfo, err error) error {
  268. if err != nil {
  269. return err
  270. }
  271. // create a local file header
  272. header, err := zip.FileInfoHeader(info)
  273. if err != nil {
  274. return err
  275. }
  276. // set compression
  277. header.Method = zip.Deflate
  278. // set relative path of a file as the header name
  279. header.Name, err = filepath.Rel(filepath.Dir(srcPath), path)
  280. if err != nil {
  281. return err
  282. }
  283. if info.IsDir() {
  284. header.Name += string(os.PathSeparator)
  285. }
  286. // create writer for the file header and save content of the file
  287. headerWriter, err := zipWriter.CreateHeader(header)
  288. if err != nil {
  289. return err
  290. }
  291. if info.IsDir() {
  292. return nil
  293. }
  294. f, err := os.Open(path)
  295. if err != nil {
  296. return err
  297. }
  298. defer f.Close()
  299. _, err = io.Copy(headerWriter, f)
  300. return err
  301. })
  302. if err != nil {
  303. return err
  304. }
  305. }
  306. return nil
  307. }