初始
This commit is contained in:
329
api/v1/common/coryCommon/downloadFile.go
Normal file
329
api/v1/common/coryCommon/downloadFile.go
Normal file
@ -0,0 +1,329 @@
|
||||
package coryCommon
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/tiger1103/gfast/v3/internal/app/system/model"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CreateZipFile 生成一个压缩文件夹,然后将指定文件夹的数据(文件及文件夹)存放到压缩文件下
|
||||
func CreateZipFile(sourceDir, zipFile string) error {
|
||||
zipFileToCreate, err := os.Create(zipFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer zipFileToCreate.Close()
|
||||
|
||||
zipWriter := zip.NewWriter(zipFileToCreate)
|
||||
defer zipWriter.Close()
|
||||
|
||||
err = filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return addFileToZip(zipWriter, path, sourceDir)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func addFileToZip(zipWriter *zip.Writer, filePath, baseDir string) error {
|
||||
fileToZip, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fileToZip.Close()
|
||||
|
||||
info, err := fileToZip.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 获取文件相对路径
|
||||
relPath, err := filepath.Rel(baseDir, filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 替换路径分隔符确保在压缩文件中使用正斜杠
|
||||
relPath = strings.ReplaceAll(relPath, `\`, "/")
|
||||
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header.Name = relPath
|
||||
|
||||
if info.IsDir() {
|
||||
header.Name += "/"
|
||||
header.Method = zip.Store // Directory
|
||||
} else {
|
||||
header.Method = zip.Deflate // File
|
||||
}
|
||||
|
||||
writer, err := zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !info.IsDir() {
|
||||
_, err = io.Copy(writer, fileToZip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MultifileDownload 【功能:多文件下载】===【参数:relativelyTemporaryPath相对路径、filesToCopy需要放在压缩包下载的文件】
|
||||
func MultifileDownload(relativelyTemporaryPath string, filesToCopy []string) (path string, err error) {
|
||||
//网络资源下载到本地
|
||||
for i := range filesToCopy {
|
||||
url := filesToCopy[i]
|
||||
pathParts := strings.Split(url, "/")
|
||||
fileName := pathParts[len(pathParts)-1]
|
||||
filePath := filepath.ToSlash(GetCWD() + Temporary + "/" + fileName)
|
||||
err = DownloadFile(url, filePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
filesToCopy[i] = filePath
|
||||
}
|
||||
|
||||
// 1、创建临时压缩包
|
||||
zipFile, zipWriter, err := createTempZip(relativelyTemporaryPath)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating temp zip:", err)
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
zipWriter.Close()
|
||||
zipFile.Close()
|
||||
//暂时不删除、创建了个每月定时清除临时文件的定时器
|
||||
//for i := range filesToCopy {
|
||||
// delFile(filesToCopy[i], 0) //删除临时文件
|
||||
//}
|
||||
//go delFile(zipFile.Name(), 20) // 删除临时压缩文件,20秒后执行,防止文件还没下载完成就给删除了
|
||||
}()
|
||||
|
||||
// 2、复制文件夹到压缩包
|
||||
for _, filePath := range filesToCopy {
|
||||
err := copyFileToZip(zipWriter, filePath)
|
||||
if err != nil {
|
||||
fmt.Printf("Error copying %s to zip: %s\n", filePath, err)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
path = strings.ReplaceAll(filepath.ToSlash(zipFile.Name()), filepath.ToSlash(GetCWD())+"/resource/public", "/file") //如果服务器同步需要注意wxfile
|
||||
return
|
||||
}
|
||||
|
||||
// 创建临时压缩包,并且提供写入数据
|
||||
func createTempZip(relativelyTemporaryPath string) (*os.File, *zip.Writer, error) {
|
||||
cwd := GetCWD() + relativelyTemporaryPath
|
||||
zipFile, err := os.CreateTemp(cwd, "temp_zip_*.zip") //*自动分配
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
zipWriter := zip.NewWriter(zipFile)
|
||||
return zipFile, zipWriter, nil
|
||||
}
|
||||
|
||||
// 复制文件到压缩包
|
||||
func copyFileToZip(zipWriter *zip.Writer, filePath string) error {
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
// 获取文件信息
|
||||
info, err := file.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 创建zip文件中的文件头
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 指定文件名
|
||||
header.Name = filepath.Base(filePath)
|
||||
// 创建zip文件中的文件
|
||||
writer, err := zipWriter.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 复制文件内容到zip文件中
|
||||
_, err = io.Copy(writer, file)
|
||||
return err
|
||||
}
|
||||
|
||||
// delFile 删除文件
|
||||
func delFile(file string, second int) {
|
||||
if second > 0 {
|
||||
time.Sleep(time.Duration(second) * time.Second)
|
||||
}
|
||||
if err := os.Remove(file); err != nil {
|
||||
fmt.Println("Failed to delete temporary file:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// DownloadFile URL资源下载到自定位置
|
||||
func DownloadFile(url, localPath string) error {
|
||||
// 发起HTTP GET请求
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 检查响应状态码
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("HTTP request failed with status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 创建本地文件
|
||||
file, err := os.Create(localPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 将HTTP响应体的内容拷贝到本地文件
|
||||
_, err = io.Copy(file, resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveAllFilesInDirectory 删除指定目录下的所有文件 例子:"D:\\Cory\\go\\中煤\\zmkg-back\\resource\\public\\temporary"
|
||||
func RemoveAllFilesInDirectory(directoryPath string) error {
|
||||
// 获取指定目录下的所有文件和子目录
|
||||
files, err := filepath.Glob(filepath.Join(directoryPath, "*"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 遍历所有文件并删除
|
||||
for _, file := range files {
|
||||
if err := os.RemoveAll(file); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Deleted:", file)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetFiles 获取目录下所有文件(包括文件夹中的文件)
|
||||
func GetFiles(folder string) (filesList []string) {
|
||||
files, _ := ioutil.ReadDir(folder)
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
GetFiles(folder + "/" + file.Name())
|
||||
} else {
|
||||
filesList = append(filesList, file.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetAllFile 获取目录下直属所有文件(不包括文件夹及其中的文件)
|
||||
func GetAllFile(pathname string) (s []string, err error) {
|
||||
rd, err := ioutil.ReadDir(pathname)
|
||||
if err != nil {
|
||||
fmt.Println("read dir fail:", err)
|
||||
return s, err
|
||||
}
|
||||
|
||||
for _, fi := range rd {
|
||||
if !fi.IsDir() {
|
||||
fullName := pathname + "/" + fi.Name()
|
||||
s = append(s, fullName)
|
||||
}
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Xcopy 复制文件
|
||||
func Xcopy(source, target string) (err error) {
|
||||
// 打开源文件
|
||||
sourceFile, err := os.Open(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sourceFile.Close()
|
||||
|
||||
// 创建目标文件
|
||||
destinationFile, err := os.Create(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer destinationFile.Close()
|
||||
|
||||
// 使用 io.Copy() 函数复制文件内容
|
||||
_, err = io.Copy(destinationFile, sourceFile)
|
||||
return err
|
||||
}
|
||||
|
||||
// CustomizationMultifileDownload 定制下载(安全考试专用)
|
||||
func CustomizationMultifileDownload(relativelyTemporaryPath string, mw []*model.ModelWeChatPdfWoRes) (path string, err error) {
|
||||
//1、创建文件夹
|
||||
paht := filepath.ToSlash(GetCWD() + "/" + Ynr(Temporary+"/"))
|
||||
folder := paht + FileName("aqks") //文件夹名
|
||||
folder = filepath.ToSlash(folder)
|
||||
folder = folder[0 : len(folder)-1]
|
||||
err = os.MkdirAll(folder, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
//2、网络资源下载到本地
|
||||
for i := range mw {
|
||||
url := mw[i].Path
|
||||
str := folder + "/" + mw[i].UserName + mw[i].Openid
|
||||
os.MkdirAll(str, 0777) //根据名字创建子目录
|
||||
//url看看是几个文件
|
||||
fileNum := strings.Split(url, ",")
|
||||
for j := range fileNum {
|
||||
if fileNum[j] != "" {
|
||||
//因为pdf是另外一个服务器所以需要下载,但是有的又是本地服务器,所以直接复制
|
||||
if strings.Contains(fileNum[j], "/wxfile/") {
|
||||
pathstr := g.Cfg().MustGet(gctx.New(), "cory").String() + fileNum[j]
|
||||
pathParts := strings.Split(pathstr, "/")
|
||||
filePath := str + "/" + pathParts[len(pathParts)-1]
|
||||
err = DownloadFile(pathstr, filePath) //下载网络图片
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
source := FileToFunc(fileNum[j], 2)
|
||||
pathParts := strings.Split(fileNum[j], "/")
|
||||
target := str + "/" + pathParts[len(pathParts)-1]
|
||||
err := Xcopy(source, target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//3、压缩成压缩包zip
|
||||
path = paht + FileName("aqks") + ".zip"
|
||||
err = CreateZipFile(folder, path)
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user