123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- package main
- import (
- "archive/zip"
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "strings"
- "github.com/axgle/mahonia"
- "github.com/nwaples/rardecode"
- "github.com/studio-b12/gowebdav"
- "golang.org/x/text/encoding/simplifiedchinese"
- "golang.org/x/text/transform"
- )
- /*
- 1.上云盘获取到zip、下载到本地
- 2.解压
- 3.上传云盘
- 4.删除本地文件
- */
- func do(archivePath, extractPath string) {
- // archivePath = "path/to/your/archive.zip" // 压缩包路径
- // extractPath = "path/to/your/extracted" // 解压路径
- err := extractAndFlatten(archivePath, extractPath)
- if err != nil {
- fmt.Printf("解压缩出错:%v\n", err)
- return
- }
- log.Println("压缩包路径:", archivePath)
- log.Println("解压路径:", extractPath)
- fmt.Println("解压缩完成!")
- }
- func extractAndFlatten(archivePath, extractPath string) error {
- // 获取压缩包后缀名
- ext := strings.ToLower(filepath.Ext(archivePath))
- switch ext {
- case ".zip":
- return extractAndFlattenZip(archivePath, extractPath)
- case ".rar":
- return extractAndFlattenRar(archivePath, extractPath)
- default:
- return fmt.Errorf("不支持的压缩格式:%s", ext)
- }
- }
- func decodeFilenameByByte(nameBytes []byte) (string, error) {
- // 创建一个 GBK 解码器
- decoder := mahonia.NewDecoder("gbk")
- // 将字节切片解码为字符串
- decodedName := decoder.ConvertString(string(nameBytes))
- return decodedName, nil
- }
- func extractAndFlattenZip(archivePath, extractPath string) error {
- r, err := zip.OpenReader(archivePath)
- if err != nil {
- return err
- }
- log.Println("---archivePath", archivePath)
- defer r.Close()
- var decodeName string
- for _, f := range r.File {
- // path := filepath.Join(extractPath, f.Name)
- // log.Println("~~~~~~~~", f.Name)
- if f.Flags == 0 {
- i := bytes.NewReader([]byte(f.Name))
- decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
- content, _ := ioutil.ReadAll(decoder)
- decodeName = string(content)
- f.Name = decodeName
- } else {
- decodeName = f.Name
- }
- path := filepath.Join(extractPath, decodeName)
- if f.FileInfo().IsDir() {
- os.MkdirAll(path, os.ModePerm)
- continue
- }
- fileReader, err := f.Open()
- if err != nil {
- return err
- }
- targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
- if err != nil {
- fileReader.Close()
- return err
- }
- _, err = io.Copy(targetFile, fileReader)
- fileReader.Close()
- targetFile.Close()
- if err != nil {
- return err
- }
- baseName := filepath.Base(f.Name)
- ext := filepath.Ext(baseName)
- //没有外层目录 取压缩包名称
- mulu := filepath.Base(filepath.Dir(f.Name))
- if filepath.Base(filepath.Dir(f.Name)) == "." {
- muluarr := strings.Split(archivePath, `/`)
- if len(muluarr) > 0 {
- mulu = muluarr[len(muluarr)-1]
- muluarr2 := strings.Split(mulu, ".")
- muluarr3 := strings.Split(muluarr2[0], "_")
- mulu = strings.Join(muluarr3[0:len(muluarr3)-1], "_")
- }
- }
- //newName := filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", filepath.Base(filepath.Dir(f.Name)), strings.TrimSuffix(baseName, ext), ext))
- newName, err := decodeFilename(filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", mulu, strings.TrimSuffix(baseName, ext), ext)))
- if err != nil {
- return err
- }
- err = os.Rename(path, newName)
- if err != nil {
- return err
- }
- }
- return nil
- }
- func extractAndFlattenRar(archivePath, extractPath string) error {
- rf, err := os.Open(archivePath)
- if err != nil {
- log.Println("rar1 err:", err)
- return err
- }
- defer rf.Close()
- reader, err := rardecode.NewReader(rf, "")
- if err != nil {
- return err
- }
- for {
- header, err := reader.Next()
- if err != nil {
- if err.Error() == "EOF" {
- break
- }
- return err
- }
- path := filepath.Join(extractPath, header.Name)
- path = strings.ReplaceAll(path, `\`, `/`)
- log.Println("===", path)
- header.Name = strings.ReplaceAll(header.Name, `\`, `/`)
- headerName := header.Name
- if arr := strings.Split(headerName, "/"); len(arr) > 0 {
- headerName = arr[len(arr)-1]
- path = strings.ReplaceAll(path, header.Name, headerName)
- }
- if header.IsDir {
- err = os.MkdirAll(path, os.ModePerm)
- if err != nil {
- return err
- }
- continue
- }
- file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, header.Mode().Perm())
- if err != nil {
- log.Println("rar err5:", err)
- return err
- }
- _, err = io.Copy(file, reader)
- file.Close()
- if err != nil {
- log.Println("rar err2:", err)
- return err
- }
- baseName := filepath.Base(header.Name)
- ext := filepath.Ext(baseName)
- //没有外层目录 取压缩包名称
- mulu := filepath.Base(filepath.Dir(header.Name))
- if filepath.Base(filepath.Dir(header.Name)) == "." {
- muluarr := strings.Split(archivePath, `/`)
- if len(muluarr) > 0 {
- mulu = muluarr[len(muluarr)-1]
- muluarr2 := strings.Split(mulu, ".")
- muluarr3 := strings.Split(muluarr2[0], "_")
- mulu = strings.Join(muluarr3[0:len(muluarr3)-1], "_")
- }
- }
- //newName := filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", filepath.Base(filepath.Dir(header.Name)), strings.TrimSuffix(baseName, ext), ext))
- newName, err := decodeFilename(filepath.Join(extractPath, fmt.Sprintf("%s_%s%s", mulu, strings.TrimSuffix(baseName, ext), ext)))
- if err != nil {
- log.Println("rar err3:", err)
- return err
- }
- err = os.Rename(path, newName)
- if err != nil {
- log.Println("rar err4:", err)
- return err
- }
- }
- log.Println("+++++++++", extractPath)
- return nil
- }
- // 获取数据目录
- func getRemoteFilePath_forunzip(webdav, user, secert, remote string) {
- log.Println("准备下载 ", remote, cf.YusuanInfo)
- client := gowebdav.NewAuthClient(webdav, gowebdav.NewAutoAuth(user, secert))
- client.Connect()
- // 获取根目录列表
- entries, err := client.ReadDir(remote)
- if err != nil {
- log.Fatal(err)
- }
- // 遍历目录结构
- for _, entry := range entries {
- log.Println(remote + "/" + entry.Name())
- if entry.IsDir() {
- // 如果是目录,则递归遍历子目录
- readDirRecursive_forunzip(client, remote+"/"+entry.Name())
- }
- }
- log.Println(fmt.Sprintf("读取文件总数量为:%d", filenum))
- }
- //年份_承德热河地质博物馆2024年预算公开_承德热河地质博物馆2024年预算公开说明.pdf
- // 递归遍历目录结构
- func readDirRecursive_forunzip(client *gowebdav.Client, path string) {
- filenum = 0 //重置数量
- entries, err := client.ReadDir(path)
- if err != nil {
- log.Fatal(err)
- }
- for _, entry := range entries {
- if entry.IsDir() {
- // 如果是目录,则递归遍历子目录
- readDirRecursive_forunzip(client, path+"/"+entry.Name())
- } else {
- filenum++
- file_path := path + "/" + entry.Name()
- yunpanPath := path
- sp1 := strings.Split(file_path, "/") //路径
- sp2 := strings.Split(entry.Name(), ".") //文件名称
- //log.Println("sp1:", sp1)
- //log.Println("sp2:", sp2)
- if len(sp2) < 2 {
- continue
- }
- ext := sp2[1]
- extMap := map[string]bool{
- "rar": true,
- "zip": true,
- }
- if !extMap[ext] {
- continue
- }
- dirpath := fmt.Sprintf("./%s", strings.ReplaceAll(strings.Join(sp1, "@#$"), ".", ""))
- log.Println(dirpath)
- //创建文件
- CreateDir(dirpath)
- //下载
- reader, err := client.ReadStream(file_path)
- if err != nil {
- log.Println("err1:", err)
- continue
- }
- downLoadPath := dirpath + "/" + entry.Name()
- fo, err := os.Create(downLoadPath)
- if err != nil {
- log.Println("err2:", err)
- continue
- }
- io.Copy(fo, reader)
- reader.Close()
- fo.Close()
- do(downLoadPath, dirpath)
- GetPDFandWORDandEXCEL(client, dirpath, yunpanPath)
- //yunpanPath
- }
- }
- }
- func GetPDFandWORDandEXCEL(client *gowebdav.Client, directory string, yunpanPath string) {
- log.Println("寻找目标文件:", directory)
- err := filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
- path = strings.ReplaceAll(path, `\`, `/`)
- if err != nil {
- log.Println("###err:", err)
- return err
- }
- // 检查文件扩展名
- ext := strings.ToLower(filepath.Ext(path))
- if ext == ".xlsx" || ext == ".xls" || ext == ".docx" || ext == ".doc" || ext == ".pdf" {
- absPath, err := filepath.Abs(path)
- if err != nil {
- log.Println("转换为绝对路径出错:", err)
- return nil
- }
- fmt.Println("最终文件:", absPath)
- UploadYunPan(client, absPath, yunpanPath)
- }
- return nil
- })
- if err != nil {
- fmt.Println("Error:", err)
- }
- }
- func UploadYunPan(client *gowebdav.Client, localFilePath, cloudFilePath string) {
- log.Println("localFilePath:", localFilePath)
- log.Println("cloudFilePath:", cloudFilePath)
- localFilePath = strings.ReplaceAll(localFilePath, `\`, `/`)
- cloudFilePath = strings.ReplaceAll(cloudFilePath, `\`, `/`)
- arr := strings.Split(localFilePath, "/")
- if len(arr) > 0 {
- cloudFilePath = cloudFilePath + "/" + "2024年_" + arr[len(arr)-1]
- }
- // 打开本地文件并读取文件内容
- file, err := os.Open(localFilePath)
- if err != nil {
- fmt.Println("打开本地文件失败:", err)
- return
- }
- defer file.Close()
- data, err := ioutil.ReadAll(file)
- if err != nil {
- fmt.Println("读取本地文件内容失败:", err)
- return
- }
- // 将文件上传到云盘
- err = client.Write(cloudFilePath, data, 0644)
- if err != nil {
- fmt.Println("上传文件到云盘失败:", err)
- return
- }
- fmt.Println("文件上传成功!")
- }
- func CreateDir(dirPath string) {
- _, err := os.Stat(dirPath)
- if os.IsNotExist(err) {
- err := os.Mkdir(dirPath, os.ModePerm)
- if err != nil {
- fmt.Printf("创建文件夹出错:%v\n", err)
- return
- }
- fmt.Println("文件夹创建成功!")
- }
- }
- func DelDir(dirPath string) {
- os.RemoveAll(dirPath)
- }
|