unarchiveFile.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package model
  2. import (
  3. "archive/tar"
  4. "archive/zip"
  5. "bytes"
  6. "compress/flate"
  7. "errors"
  8. "fmt"
  9. "github.com/gen2brain/go-unarr"
  10. "github.com/go-rod/rod/lib/utils"
  11. "github.com/mholt/archiver/v3"
  12. "github.com/saintfish/chardet"
  13. "golang.org/x/text/encoding/simplifiedchinese"
  14. "golang.org/x/text/transform"
  15. "io"
  16. "io/ioutil"
  17. "path"
  18. "path/filepath"
  19. "strings"
  20. "unicode/utf8"
  21. )
  22. func UnArchiveFile(fileFullPath, desRootPath string) error {
  23. switch filepath.Ext(strings.ToLower(fileFullPath)) {
  24. case ".zip":
  25. z := archiver.Zip{
  26. CompressionLevel: flate.DefaultCompression,
  27. MkdirAll: true,
  28. SelectiveCompression: true,
  29. ContinueOnError: false,
  30. OverwriteExisting: false,
  31. ImplicitTopLevelFolder: false,
  32. }
  33. err := z.Walk(fileFullPath, func(f archiver.File) error {
  34. if f.IsDir() == true {
  35. return nil
  36. }
  37. zfh, ok := f.Header.(zip.FileHeader)
  38. if ok {
  39. isUTF8 := utf8.Valid([]byte(zfh.Name))
  40. if isUTF8 != zfh.NonUTF8 {
  41. println("the same")
  42. } else {
  43. println("not the same")
  44. }
  45. err := processOneFile(f, zfh.NonUTF8, desRootPath)
  46. if err != nil {
  47. return err
  48. }
  49. }
  50. return nil
  51. })
  52. if err != nil {
  53. return err
  54. }
  55. case ".tar":
  56. z := archiver.Tar{
  57. MkdirAll: true,
  58. ContinueOnError: false,
  59. OverwriteExisting: false,
  60. ImplicitTopLevelFolder: false,
  61. }
  62. err := z.Walk(fileFullPath, func(f archiver.File) error {
  63. if f.IsDir() == true {
  64. return nil
  65. }
  66. zfh, ok := f.Header.(tar.Header)
  67. if ok {
  68. err := processOneFile(f, utf8.Valid([]byte(zfh.Name)), desRootPath)
  69. if err != nil {
  70. return err
  71. }
  72. }
  73. return nil
  74. })
  75. if err != nil {
  76. return err
  77. }
  78. case ".rar":
  79. z := archiver.Rar{
  80. MkdirAll: true,
  81. ContinueOnError: false,
  82. OverwriteExisting: false,
  83. ImplicitTopLevelFolder: false,
  84. }
  85. err := z.Walk(fileFullPath, func(f archiver.File) error {
  86. if f.IsDir() == true {
  87. return nil
  88. }
  89. zfh, ok := f.Header.(tar.Header)
  90. if ok {
  91. err := processOneFile(f, utf8.Valid([]byte(zfh.Name)), desRootPath)
  92. if err != nil {
  93. return err
  94. }
  95. }
  96. return nil
  97. })
  98. if err != nil {
  99. return err
  100. }
  101. default:
  102. return errors.New("not support un archive file ext")
  103. }
  104. return nil
  105. }
  106. func processOneFile(f archiver.File, notUTF8 bool, desRootPath string) error {
  107. detector := chardet.NewTextDetector()
  108. decodeName := f.Name()
  109. result, err := detector.DetectBest([]byte(decodeName))
  110. if err != nil {
  111. return err
  112. }
  113. fmt.Printf("Detected charset is %s, language is %s",
  114. result.Charset,
  115. result.Language)
  116. if notUTF8 == true {
  117. i := bytes.NewReader([]byte(f.Name()))
  118. decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
  119. content, _ := ioutil.ReadAll(decoder)
  120. decodeName = string(content)
  121. }
  122. var chunk []byte
  123. buf := make([]byte, 1024)
  124. for {
  125. n, err := f.Read(buf)
  126. if err != nil && err != io.EOF {
  127. return err
  128. }
  129. //说明读取结束
  130. if n == 0 {
  131. break
  132. }
  133. //读取到最终的缓冲区中
  134. chunk = append(chunk, buf[:n]...)
  135. }
  136. err = utils.OutputFile(path.Join(desRootPath, decodeName), chunk)
  137. if err != nil {
  138. return err
  139. }
  140. return nil
  141. }
  142. func UnArr(fileFullPath, desRootPath string) error {
  143. a, err := unarr.NewArchive(fileFullPath)
  144. if err != nil {
  145. return err
  146. }
  147. defer a.Close()
  148. for {
  149. err := a.Entry()
  150. if err != nil {
  151. if err == io.EOF {
  152. break
  153. } else {
  154. return err
  155. }
  156. }
  157. data, err := a.ReadAll()
  158. if err != nil {
  159. return err
  160. }
  161. decodeName := a.Name()
  162. decodeName = filepath.Base(decodeName)
  163. err = utils.OutputFile(path.Join(desRootPath, decodeName), data)
  164. if err != nil {
  165. return err
  166. }
  167. }
  168. return nil
  169. }