unarchiveFile.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package archive_helper
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "golang.org/x/text/encoding/simplifiedchinese"
  6. "golang.org/x/text/transform"
  7. "io/ioutil"
  8. "compress/flate"
  9. "errors"
  10. "github.com/gen2brain/go-unarr"
  11. "github.com/go-rod/rod/lib/utils"
  12. "github.com/mholt/archiver/v3"
  13. "io"
  14. "path"
  15. "path/filepath"
  16. "strings"
  17. )
  18. // UnArchiveFile 7z 以外的都能搞定中文编码的问题,但是 7z 有梗,需要单独的库去解析,且编码是解决不了的,以后他们搞定了再测试
  19. // 所以效果就是,7z 外的压缩包文件解压ok,字幕可以正常从名称解析出是简体还是繁体,但是7z就没办法了,一定乱码
  20. func UnArchiveFile(fileFullPath, desRootPath string) error {
  21. switch filepath.Ext(strings.ToLower(fileFullPath)) {
  22. case ".zip":
  23. z := archiver.Zip{
  24. CompressionLevel: flate.DefaultCompression,
  25. MkdirAll: true,
  26. SelectiveCompression: true,
  27. ContinueOnError: false,
  28. OverwriteExisting: false,
  29. ImplicitTopLevelFolder: false,
  30. }
  31. err := z.Walk(fileFullPath, func(f archiver.File) error {
  32. if f.IsDir() == true {
  33. return nil
  34. }
  35. zfh, ok := f.Header.(zip.FileHeader)
  36. if ok {
  37. err := processOneFile(f, zfh.NonUTF8, desRootPath)
  38. if err != nil {
  39. return err
  40. }
  41. }
  42. return nil
  43. })
  44. if err != nil {
  45. return err
  46. }
  47. case ".tar":
  48. z := archiver.Tar{
  49. MkdirAll: true,
  50. ContinueOnError: false,
  51. OverwriteExisting: false,
  52. ImplicitTopLevelFolder: false,
  53. StripComponents: 1,
  54. }
  55. err := z.Walk(fileFullPath, func(f archiver.File) error {
  56. if f.IsDir() == true {
  57. return nil
  58. }
  59. err := processOneFile(f, false, desRootPath)
  60. if err != nil {
  61. return err
  62. }
  63. return nil
  64. })
  65. if err != nil {
  66. return err
  67. }
  68. case ".rar":
  69. z := archiver.Rar{
  70. MkdirAll: true,
  71. ContinueOnError: false,
  72. OverwriteExisting: false,
  73. ImplicitTopLevelFolder: false,
  74. StripComponents: 1,
  75. }
  76. err := z.Walk(fileFullPath, func(f archiver.File) error {
  77. if f.IsDir() == true {
  78. return nil
  79. }
  80. err := processOneFile(f, false, desRootPath)
  81. if err != nil {
  82. return err
  83. }
  84. return nil
  85. })
  86. if err != nil {
  87. return err
  88. }
  89. case ".7z":
  90. return unArr7z(fileFullPath, desRootPath)
  91. default:
  92. return errors.New("not support un archive file ext")
  93. }
  94. return nil
  95. }
  96. func processOneFile(f archiver.File, notUTF8 bool, desRootPath string) error {
  97. decodeName := f.Name()
  98. if notUTF8 == true {
  99. //ouBytes, err := ChangeFileCoding2UTF8([]byte(f.Name()))
  100. //if err != nil {
  101. // return err
  102. //}
  103. i := bytes.NewReader([]byte(f.Name()))
  104. decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
  105. content, _ := ioutil.ReadAll(decoder)
  106. decodeName = string(content)
  107. //decodeName = string(ouBytes)
  108. }
  109. var chunk []byte
  110. buf := make([]byte, 1024)
  111. for {
  112. n, err := f.Read(buf)
  113. if err != nil && err != io.EOF {
  114. return err
  115. }
  116. //说明读取结束
  117. if n == 0 {
  118. break
  119. }
  120. //读取到最终的缓冲区中
  121. chunk = append(chunk, buf[:n]...)
  122. }
  123. err := utils.OutputFile(path.Join(desRootPath, decodeName), chunk)
  124. if err != nil {
  125. return err
  126. }
  127. return nil
  128. }
  129. func unArr7z(fileFullPath, desRootPath string) error {
  130. a, err := unarr.NewArchive(fileFullPath)
  131. if err != nil {
  132. return err
  133. }
  134. defer a.Close()
  135. for {
  136. err := a.Entry()
  137. if err != nil {
  138. if err == io.EOF {
  139. break
  140. } else {
  141. return err
  142. }
  143. }
  144. data, err := a.ReadAll()
  145. if err != nil {
  146. return err
  147. }
  148. decodeName := a.Name()
  149. decodeName = filepath.Base(decodeName)
  150. err = utils.OutputFile(path.Join(desRootPath, decodeName), data)
  151. if err != nil {
  152. return err
  153. }
  154. }
  155. return nil
  156. }
  157. func IsWantedArchiveExtName(fileName string) bool {
  158. switch strings.ToLower(filepath.Ext(fileName)) {
  159. case ".zip", ".tar",".rar", "7z":
  160. return true
  161. default:
  162. return false
  163. }
  164. }