|
@@ -4,128 +4,143 @@ import (
|
|
|
"archive/zip"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
+ "io/fs"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
+ "strings"
|
|
|
)
|
|
|
|
|
|
-// func Zip(zipPath string, paths ...string) error {
|
|
|
-// // Create zip file and it's parent dir.
|
|
|
-// if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// archive, err := os.Create(zipPath)
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// defer archive.Close()
|
|
|
-
|
|
|
-// // New zip writer.
|
|
|
-// zipWriter := zip.NewWriter(archive)
|
|
|
-// defer zipWriter.Close()
|
|
|
-
|
|
|
-// // Traverse the file or directory.
|
|
|
-// for _, rootPath := range paths {
|
|
|
-// // Remove the trailing path separator if path is a directory.
|
|
|
-// rootPath = strings.TrimSuffix(rootPath, string(os.PathSeparator))
|
|
|
-
|
|
|
-// // Visit all the files or directories in the tree.
|
|
|
-// err = filepath.Walk(rootPath, walkFunc(rootPath, zipWriter))
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-
|
|
|
-// func walkFunc(rootPath string, zipWriter *zip.Writer) filepath.WalkFunc {
|
|
|
-// return func(path string, info fs.FileInfo, err error) error {
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-
|
|
|
-// // If a file is a symbolic link it will be skipped.
|
|
|
-// if info.Mode()&os.ModeSymlink != 0 {
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-
|
|
|
-// // Create a local file header.
|
|
|
-// header, err := zip.FileInfoHeader(info)
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-
|
|
|
-// // Set compression method.
|
|
|
-// header.Method = zip.Deflate
|
|
|
-
|
|
|
-// // Set relative path of a file as the header name.
|
|
|
-// header.Name, err = filepath.Rel(filepath.Dir(rootPath), path)
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// if info.IsDir() {
|
|
|
-// header.Name += string(os.PathSeparator)
|
|
|
-// }
|
|
|
-
|
|
|
-// // Create writer for the file header and save content of the file.
|
|
|
-// headerWriter, err := zipWriter.CreateHeader(header)
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// if info.IsDir() {
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-// f, err := os.Open(path)
|
|
|
-// if err != nil {
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// defer f.Close()
|
|
|
-// _, err = io.Copy(headerWriter, f)
|
|
|
-// return err
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-func Zip(zip_file_name string, src_dir string) {
|
|
|
-
|
|
|
- // 预防:旧文件无法覆盖
|
|
|
- os.RemoveAll(zip_file_name)
|
|
|
-
|
|
|
- // 创建:zip文件
|
|
|
- zipfile, _ := os.Create(zip_file_name)
|
|
|
- defer zipfile.Close()
|
|
|
-
|
|
|
- // 打开:zip文件
|
|
|
- archive := zip.NewWriter(zipfile)
|
|
|
+func Zip(zipPath string, paths ...string) error {
|
|
|
+ // Create zip file and it's parent dir.
|
|
|
+ if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ archive, err := os.Create(zipPath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
defer archive.Close()
|
|
|
|
|
|
- // 遍历路径信息
|
|
|
- filepath.Walk(src_dir, func(path string, info os.FileInfo, _ error) error {
|
|
|
+ // New zip writer.
|
|
|
+ zipWriter := zip.NewWriter(archive)
|
|
|
+ defer zipWriter.Close()
|
|
|
|
|
|
- // 如果是源路径,提前进行下一个遍历
|
|
|
- if path == src_dir {
|
|
|
+ // Traverse the file or directory.
|
|
|
+ for _, rootPath := range paths {
|
|
|
+ // Remove the trailing path separator if path is a directory.
|
|
|
+ rootPath = strings.TrimSuffix(rootPath, string(os.PathSeparator))
|
|
|
+
|
|
|
+ // Visit all the files or directories in the tree.
|
|
|
+ err = filepath.Walk(rootPath, walkFunc(rootPath, zipWriter))
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func walkFunc(rootPath string, zipWriter *zip.Writer) filepath.WalkFunc {
|
|
|
+ return func(path string, info fs.FileInfo, err error) error {
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // If a file is a symbolic link it will be skipped.
|
|
|
+ if info.Mode()&os.ModeSymlink != 0 {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- // 获取:文件头信息
|
|
|
- header, _ := zip.FileInfoHeader(info)
|
|
|
- // path, _ = filepath.Rel(src_dir, path)
|
|
|
+ // Create a local file header.
|
|
|
+ header, err := zip.FileInfoHeader(info)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set compression method.
|
|
|
+ header.Method = zip.Deflate
|
|
|
+
|
|
|
+ // Set relative path of a file as the header name.
|
|
|
+ header.Name, err = filepath.Rel(filepath.Dir(rootPath), path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if info.IsDir() {
|
|
|
+ // header.Name += string(os.PathSeparator)
|
|
|
+ header.Name += "\\"
|
|
|
+ fmt.Println(header.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create writer for the file header and save content of the file.
|
|
|
+ headerWriter, err := zipWriter.CreateHeader(header)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if info.IsDir() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
fmt.Println(path)
|
|
|
- header.Name, _ = filepath.Rel(src_dir, path)
|
|
|
+ fmt.Println(header.Name)
|
|
|
+ f, err := os.Open(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer f.Close()
|
|
|
+ _, err = io.Copy(headerWriter, f)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // 判断:文件是不是文件夹
|
|
|
+func ZipFile(srcFile, destFile string) error {
|
|
|
+ // 创建目标文件,即zip文件
|
|
|
+ zipFile, err := os.Create(destFile)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer zipFile.Close()
|
|
|
+ // 创建writer,准备向目标文件中写入数据
|
|
|
+ writer := zip.NewWriter(zipFile)
|
|
|
+ defer writer.Close()
|
|
|
+
|
|
|
+ // 遍历文件(如果srcFile是个目录的话)
|
|
|
+ err = filepath.Walk(srcFile, func(path string, info os.FileInfo, err error) error {
|
|
|
+ // 遍历发生错误,退出
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建zip文件信息头
|
|
|
+ header, err := zip.FileInfoHeader(info)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ header.Name = path
|
|
|
if info.IsDir() {
|
|
|
- header.Name += `/`
|
|
|
+ header.Name += "\\"
|
|
|
} else {
|
|
|
- // 设置:zip的文件压缩算法
|
|
|
header.Method = zip.Deflate
|
|
|
}
|
|
|
|
|
|
- // 创建:压缩包头部信息
|
|
|
- writer, _ := archive.CreateHeader(header)
|
|
|
- if !info.IsDir() {
|
|
|
- file, _ := os.Open(path)
|
|
|
- defer file.Close()
|
|
|
- io.Copy(writer, file)
|
|
|
+ // 将信息头写入到writer中
|
|
|
+ writer, err := writer.CreateHeader(header)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
- return nil
|
|
|
+
|
|
|
+ // 如果是目录,直接写个头就可以了,filepath.Walk会继续遍历目录
|
|
|
+ if info.IsDir() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果是文件,则将文件内容写入到writer中
|
|
|
+ file, err := os.Open(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+ _, err = io.Copy(writer, file)
|
|
|
+
|
|
|
+ return err
|
|
|
})
|
|
|
+
|
|
|
+ return err
|
|
|
}
|