Files
zmkgC/api/v1/common/tool/zip/zip.go
2025-07-07 20:11:59 +08:00

114 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package zip
import (
"archive/zip"
"fmt"
"io"
"os"
"path"
)
func ZipFiles(filename string, files []string) error {
fmt.Println("start zip file......")
//创建输出文件目录
newZipFile, err := os.Create(filename)
if err != nil {
return err
}
defer newZipFile.Close()
//创建空的zip档案可以理解为打开zip文件准备写入
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
// Add files to zip
for _, file := range files {
if err = AddFileToZip(zipWriter, file); err != nil {
return err
}
}
return nil
}
func AddFileToZip(zipWriter *zip.Writer, filename string) error {
//打开要压缩的文件
fileToZip, err := os.Open(filename)
if err != nil {
return err
}
defer fileToZip.Close()
//获取文件的描述
info, err := fileToZip.Stat()
if err != nil {
return err
}
//FileInfoHeader返回一个根据fi填写了部分字段的Header可以理解成是将fileinfo转换成zip格式的文件信息
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
header.Name = filename
/*
预定义压缩算法。
archive/zip包中预定义的有两种压缩方式。一个是仅把文件写入到zip中。不做压缩。一种是压缩文件然后写入到zip中。默认的Store模式。就是只保存不压缩的模式。
Store unit16 = 0 //仅存储文件
Deflate unit16 = 8 //压缩文件
*/
header.Method = zip.Store
//创建压缩包头部信息
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
//将源复制到目标将fileToZip 写入writer 是按默认的缓冲区32k循环操作的不会将内容一次性全写入内存中,这样就能解决大文件的问题
_, err = io.Copy(writer, fileToZip)
return err
}
// Decompressor 解压
func Decompressor(zipFilePath string, targetDir string, filename string) error {
reader, err := zip.OpenReader(zipFilePath)
if nil != err {
fmt.Println(err)
return err
}
defer reader.Close()
_ = os.MkdirAll(targetDir, 0777)
names := []string{}
for _, f := range reader.File {
err := func() error {
if f.FileInfo().IsDir() {
_ = os.MkdirAll(path.Join(targetDir, f.Name), f.Mode())
return nil
}
suffix := path.Ext(f.Name)
//fmt.Println(f.Name)
//fmt.Println(path.Join(targetDir, f.Name))
writeFile, err := os.OpenFile(path.Join(targetDir, filename+suffix), os.O_WRONLY|os.O_CREATE, f.Mode())
if nil != err {
return err
}
defer writeFile.Close()
readFile, err := f.Open()
if nil != err {
return err
}
defer readFile.Close()
n, err := io.Copy(writeFile, readFile)
if nil != err {
return err
}
if false {
names = append(names, f.Name)
fmt.Printf("解压文件: %s 大小: %v", f.Name, n)
}
return nil
}()
if nil != err {
return err
}
}
return nil
}