upzip.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. package main
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "log"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "github.com/axgle/mahonia"
  13. "github.com/nwaples/rardecode"
  14. "github.com/studio-b12/gowebdav"
  15. "golang.org/x/text/encoding/simplifiedchinese"
  16. "golang.org/x/text/transform"
  17. )
  18. /*
  19. 1.上云盘获取到zip、下载到本地
  20. 2.解压
  21. 3.上传云盘
  22. 4.删除本地文件
  23. */
  24. func do(archivePath, extractPath string) {
  25. // archivePath = "path/to/your/archive.zip" // 压缩包路径
  26. // extractPath = "path/to/your/extracted" // 解压路径
  27. err := extractAndFlatten(archivePath, extractPath)
  28. if err != nil {
  29. fmt.Printf("解压缩出错:%v\n", err)
  30. return
  31. }
  32. log.Println("压缩包路径:", archivePath)
  33. log.Println("解压路径:", extractPath)
  34. fmt.Println("解压缩完成!")
  35. }
  36. func extractAndFlatten(archivePath, extractPath string) error {
  37. // 获取压缩包后缀名
  38. ext := strings.ToLower(filepath.Ext(archivePath))
  39. switch ext {
  40. case ".zip":
  41. return extractAndFlattenZip(archivePath, extractPath)
  42. case ".rar":
  43. return extractAndFlattenRar(archivePath, extractPath)
  44. default:
  45. return fmt.Errorf("不支持的压缩格式:%s", ext)
  46. }
  47. }
  48. func decodeFilenameByByte(nameBytes []byte) (string, error) {
  49. // 创建一个 GBK 解码器
  50. decoder := mahonia.NewDecoder("gbk")
  51. // 将字节切片解码为字符串
  52. decodedName := decoder.ConvertString(string(nameBytes))
  53. return decodedName, nil
  54. }
  55. func extractAndFlattenZip(archivePath, extractPath string) error {
  56. r, err := zip.OpenReader(archivePath)
  57. if err != nil {
  58. return err
  59. }
  60. log.Println("---archivePath", archivePath)
  61. defer r.Close()
  62. var decodeName string
  63. for _, f := range r.File {
  64. // path := filepath.Join(extractPath, f.Name)
  65. // log.Println("~~~~~~~~", f.Name)
  66. if f.Flags == 0 {
  67. i := bytes.NewReader([]byte(f.Name))
  68. decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
  69. content, _ := ioutil.ReadAll(decoder)
  70. decodeName = string(content)
  71. f.Name = decodeName
  72. } else {
  73. decodeName = f.Name
  74. }
  75. path := filepath.Join(extractPath, decodeName)
  76. if f.FileInfo().IsDir() {
  77. os.MkdirAll(path, os.ModePerm)
  78. continue
  79. }
  80. fileReader, err := f.Open()
  81. if err != nil {
  82. return err
  83. }
  84. targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
  85. if err != nil {
  86. fileReader.Close()
  87. return err
  88. }
  89. _, err = io.Copy(targetFile, fileReader)
  90. fileReader.Close()
  91. targetFile.Close()
  92. if err != nil {
  93. return err
  94. }
  95. baseName := filepath.Base(f.Name)
  96. ext := filepath.Ext(baseName)
  97. //没有外层目录 取压缩包名称
  98. mulu := filepath.Base(filepath.Dir(f.Name))
  99. if filepath.Base(filepath.Dir(f.Name)) == "." {
  100. muluarr := strings.Split(archivePath, `/`)
  101. if len(muluarr) > 0 {
  102. mulu = muluarr[len(muluarr)-1]
  103. muluarr2 := strings.Split(mulu, ".")
  104. muluarr3 := strings.Split(muluarr2[0], "_")
  105. mulu = strings.Join(muluarr3[0:len(muluarr3)-1], "_")
  106. }
  107. }
  108. //newName := filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", filepath.Base(filepath.Dir(f.Name)), strings.TrimSuffix(baseName, ext), ext))
  109. newName, err := decodeFilename(filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", mulu, strings.TrimSuffix(baseName, ext), ext)))
  110. if err != nil {
  111. return err
  112. }
  113. err = os.Rename(path, newName)
  114. if err != nil {
  115. return err
  116. }
  117. }
  118. return nil
  119. }
  120. func extractAndFlattenRar(archivePath, extractPath string) error {
  121. rf, err := os.Open(archivePath)
  122. if err != nil {
  123. log.Println("rar1 err:", err)
  124. return err
  125. }
  126. defer rf.Close()
  127. reader, err := rardecode.NewReader(rf, "")
  128. if err != nil {
  129. return err
  130. }
  131. for {
  132. header, err := reader.Next()
  133. if err != nil {
  134. if err.Error() == "EOF" {
  135. break
  136. }
  137. return err
  138. }
  139. path := filepath.Join(extractPath, header.Name)
  140. path = strings.ReplaceAll(path, `\`, `/`)
  141. log.Println("===", path)
  142. header.Name = strings.ReplaceAll(header.Name, `\`, `/`)
  143. headerName := header.Name
  144. if arr := strings.Split(headerName, "/"); len(arr) > 0 {
  145. headerName = arr[len(arr)-1]
  146. path = strings.ReplaceAll(path, header.Name, headerName)
  147. }
  148. if header.IsDir {
  149. err = os.MkdirAll(path, os.ModePerm)
  150. if err != nil {
  151. return err
  152. }
  153. continue
  154. }
  155. file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, header.Mode().Perm())
  156. if err != nil {
  157. log.Println("rar err5:", err)
  158. return err
  159. }
  160. _, err = io.Copy(file, reader)
  161. file.Close()
  162. if err != nil {
  163. log.Println("rar err2:", err)
  164. return err
  165. }
  166. baseName := filepath.Base(header.Name)
  167. ext := filepath.Ext(baseName)
  168. //没有外层目录 取压缩包名称
  169. mulu := filepath.Base(filepath.Dir(header.Name))
  170. if filepath.Base(filepath.Dir(header.Name)) == "." {
  171. muluarr := strings.Split(archivePath, `/`)
  172. if len(muluarr) > 0 {
  173. mulu = muluarr[len(muluarr)-1]
  174. muluarr2 := strings.Split(mulu, ".")
  175. muluarr3 := strings.Split(muluarr2[0], "_")
  176. mulu = strings.Join(muluarr3[0:len(muluarr3)-1], "_")
  177. }
  178. }
  179. //newName := filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", filepath.Base(filepath.Dir(header.Name)), strings.TrimSuffix(baseName, ext), ext))
  180. newName, err := decodeFilename(filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", mulu, strings.TrimSuffix(baseName, ext), ext)))
  181. if err != nil {
  182. log.Println("rar err3:", err)
  183. return err
  184. }
  185. err = os.Rename(path, newName)
  186. if err != nil {
  187. log.Println("rar err4:", err)
  188. return err
  189. }
  190. }
  191. log.Println("+++++++++", extractPath)
  192. return nil
  193. }
  194. // 获取数据目录
  195. func getRemoteFilePath_forunzip(webdav, user, secert, remote string) {
  196. log.Println("准备下载 ", remote, cf.YusuanInfo)
  197. client := gowebdav.NewAuthClient(webdav, gowebdav.NewAutoAuth(user, secert))
  198. client.Connect()
  199. // 获取根目录列表
  200. entries, err := client.ReadDir(remote)
  201. if err != nil {
  202. log.Fatal(err)
  203. }
  204. // 遍历目录结构
  205. for _, entry := range entries {
  206. log.Println(remote + "/" + entry.Name())
  207. if entry.IsDir() {
  208. // 如果是目录,则递归遍历子目录
  209. readDirRecursive_forunzip(client, remote+"/"+entry.Name())
  210. }
  211. }
  212. log.Println(fmt.Sprintf("读取文件总数量为:%d", filenum))
  213. }
  214. //年份_承德热河地质博物馆2024年预算公开_承德热河地质博物馆2024年预算公开说明.pdf
  215. // 递归遍历目录结构
  216. func readDirRecursive_forunzip(client *gowebdav.Client, path string) {
  217. filenum = 0 //重置数量
  218. entries, err := client.ReadDir(path)
  219. if err != nil {
  220. log.Fatal(err)
  221. }
  222. for _, entry := range entries {
  223. if entry.IsDir() {
  224. // 如果是目录,则递归遍历子目录
  225. readDirRecursive_forunzip(client, path+"/"+entry.Name())
  226. } else {
  227. filenum++
  228. file_path := path + "/" + entry.Name()
  229. yunpanPath := path
  230. sp1 := strings.Split(file_path, "/") //路径
  231. sp2 := strings.Split(entry.Name(), ".") //文件名称
  232. //log.Println("sp1:", sp1)
  233. //log.Println("sp2:", sp2)
  234. if len(sp2) < 2 {
  235. continue
  236. }
  237. ext := sp2[1]
  238. extMap := map[string]bool{
  239. "rar": true,
  240. "zip": true,
  241. }
  242. if !extMap[ext] {
  243. continue
  244. }
  245. dirpath := fmt.Sprintf("./%s", strings.ReplaceAll(strings.Join(sp1, "@#$"), ".", ""))
  246. log.Println(dirpath)
  247. //创建文件
  248. CreateDir(dirpath)
  249. //下载
  250. reader, err := client.ReadStream(file_path)
  251. if err != nil {
  252. log.Println("err1:", err)
  253. continue
  254. }
  255. downLoadPath := dirpath + "/" + entry.Name()
  256. fo, err := os.Create(downLoadPath)
  257. if err != nil {
  258. log.Println("err2:", err)
  259. continue
  260. }
  261. io.Copy(fo, reader)
  262. reader.Close()
  263. fo.Close()
  264. do(downLoadPath, dirpath)
  265. GetPDFandWORDandEXCEL(client, dirpath, yunpanPath)
  266. //yunpanPath
  267. }
  268. }
  269. }
  270. func GetPDFandWORDandEXCEL(client *gowebdav.Client, directory string, yunpanPath string) {
  271. log.Println("寻找目标文件:", directory)
  272. err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
  273. path = strings.ReplaceAll(path, `\`, `/`)
  274. if err != nil {
  275. log.Println("###err:", err)
  276. return err
  277. }
  278. // 检查文件扩展名
  279. ext := strings.ToLower(filepath.Ext(path))
  280. if ext == ".xlsx" || ext == ".xls" || ext == ".docx" || ext == ".doc" || ext == ".pdf" {
  281. absPath, err := filepath.Abs(path)
  282. if err != nil {
  283. log.Println("转换为绝对路径出错:", err)
  284. return nil
  285. }
  286. fmt.Println("最终文件:", absPath)
  287. UploadYunPan(client, absPath, yunpanPath)
  288. }
  289. return nil
  290. })
  291. if err != nil {
  292. fmt.Println("Error:", err)
  293. }
  294. }
  295. func UploadYunPan(client *gowebdav.Client, localFilePath, cloudFilePath string) {
  296. log.Println("localFilePath:", localFilePath)
  297. log.Println("cloudFilePath:", cloudFilePath)
  298. localFilePath = strings.ReplaceAll(localFilePath, `\`, `/`)
  299. cloudFilePath = strings.ReplaceAll(cloudFilePath, `\`, `/`)
  300. arr := strings.Split(localFilePath, "/")
  301. if len(arr) > 0 {
  302. cloudFilePath = cloudFilePath + "/" + "2024年_" + arr[len(arr)-1]
  303. }
  304. // 打开本地文件并读取文件内容
  305. file, err := os.Open(localFilePath)
  306. if err != nil {
  307. fmt.Println("打开本地文件失败:", err)
  308. return
  309. }
  310. defer file.Close()
  311. data, err := ioutil.ReadAll(file)
  312. if err != nil {
  313. fmt.Println("读取本地文件内容失败:", err)
  314. return
  315. }
  316. // 将文件上传到云盘
  317. err = client.Write(cloudFilePath, data, 0644)
  318. if err != nil {
  319. fmt.Println("上传文件到云盘失败:", err)
  320. return
  321. }
  322. fmt.Println("文件上传成功!")
  323. }
  324. func CreateDir(dirPath string) {
  325. _, err := os.Stat(dirPath)
  326. if os.IsNotExist(err) {
  327. err := os.Mkdir(dirPath, os.ModePerm)
  328. if err != nil {
  329. fmt.Printf("创建文件夹出错:%v\n", err)
  330. return
  331. }
  332. fmt.Println("文件夹创建成功!")
  333. }
  334. }
  335. func DelDir(dirPath string) {
  336. os.RemoveAll(dirPath)
  337. }