index.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package compression
  2. import (
  3. "archive/zip"
  4. "github.com/druidcaesa/gotool/openfile"
  5. "io"
  6. "log"
  7. "os"
  8. "strings"
  9. )
  10. type ZipUtils struct {
  11. f openfile.FileUtils
  12. }
  13. // Compress 压缩文件
  14. //files 文件数组 可以是多目录文件
  15. //dest 压缩文件存放地址
  16. func (z ZipUtils) Compress(files []*os.File, dest string) (bool, error) {
  17. for _, file := range files {
  18. //防止用户打开os未关闭,这里调用方法前设置结束关闭
  19. defer file.Close()
  20. }
  21. //判断文件是否存在,存在的话删除
  22. if z.f.Exists(dest) {
  23. _, err := z.f.RemoveFile(dest)
  24. if err != nil {
  25. log.Fatal(err)
  26. return false, err
  27. }
  28. }
  29. d, _ := os.Create(dest)
  30. defer d.Close()
  31. w := zip.NewWriter(d)
  32. defer w.Close()
  33. for _, file := range files {
  34. err := compress(file, "", w)
  35. if err != nil {
  36. return false, err
  37. }
  38. }
  39. return true, nil
  40. }
  41. func compress(file *os.File, prefix string, zw *zip.Writer) error {
  42. info, err := file.Stat()
  43. if err != nil {
  44. return err
  45. }
  46. if info.IsDir() {
  47. prefix = prefix + "/" + info.Name()
  48. fileInfos, err := file.Readdir(-1)
  49. if err != nil {
  50. return err
  51. }
  52. for _, fi := range fileInfos {
  53. f, err := os.Open(file.Name() + "/" + fi.Name())
  54. if err != nil {
  55. return err
  56. }
  57. err = compress(f, prefix, zw)
  58. if err != nil {
  59. return err
  60. }
  61. }
  62. } else {
  63. header, err := zip.FileInfoHeader(info)
  64. header.Name = prefix + "/" + header.Name
  65. if err != nil {
  66. return err
  67. }
  68. writer, err := zw.CreateHeader(header)
  69. if err != nil {
  70. return err
  71. }
  72. _, err = io.Copy(writer, file)
  73. file.Close()
  74. if err != nil {
  75. return err
  76. }
  77. }
  78. return nil
  79. }
  80. // DeCompress 解压
  81. func (ZipUtils) DeCompress(zipFile, dest string) (bool, error) {
  82. reader, err := zip.OpenReader(zipFile)
  83. if err != nil {
  84. return false, err
  85. }
  86. defer reader.Close()
  87. for _, file := range reader.File {
  88. rc, err := file.Open()
  89. if err != nil {
  90. return false, err
  91. }
  92. defer rc.Close()
  93. filename := dest + file.Name
  94. err = os.MkdirAll(getDir(filename), 0755)
  95. if err != nil {
  96. return false, err
  97. }
  98. w, err := os.Create(filename)
  99. if err != nil {
  100. return false, err
  101. }
  102. defer w.Close()
  103. _, err = io.Copy(w, rc)
  104. if err != nil {
  105. return false, err
  106. }
  107. w.Close()
  108. rc.Close()
  109. }
  110. return true, nil
  111. }
  112. func getDir(path string) string {
  113. return subString(path, 0, strings.LastIndex(path, "/"))
  114. }
  115. func subString(str string, start, end int) string {
  116. rs := []rune(str)
  117. length := len(rs)
  118. if start < 0 || start > length {
  119. panic("start is wrong")
  120. }
  121. if end < start || end > length {
  122. panic("end is wrong")
  123. }
  124. return string(rs[start:end])
  125. }