package compression import ( "archive/zip" "io" "os" "path/filepath" "strings" ) // 参考 https://www.cnblogs.com/super-codex/articles/17124567.html type ZipHandler struct { } func NewZipHandler() *ZipHandler { return &ZipHandler{} } // UnZip // 解压zip文件到指定目录,包含顶层文件夹 func (z *ZipHandler) UnZip(src, dst string) error { archive, err := zip.OpenReader(src) if err != nil { return err } defer func(archive *zip.ReadCloser) { err := archive.Close() if err != nil { return } }(archive) for _, item := range archive.File { filePath := filepath.Join(dst, item.Name) if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } if item.FileInfo().IsDir() { err := os.MkdirAll(filePath, os.ModePerm) if err != nil { return err } continue } file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, item.Mode()) if err != nil { return err } fileInArchive, err := item.Open() if err != nil { return err } if _, err := io.Copy(file, fileInArchive); err != nil { return err } } return nil } // UnZipTo // 解压zip文件到指定目录,不包含顶层文件夹,只是将文件解压到指定目录 func (z *ZipHandler) UnZipTo(src, dst string) error { archive, err := zip.OpenReader(src) if err != nil { return err } defer func(archive *zip.ReadCloser) { err := archive.Close() if err != nil { return } }(archive) for _, item := range archive.File { splitPath := strings.Split(item.Name, string(os.PathSeparator)) targetPath := strings.Join(splitPath[1:], string(os.PathSeparator)) filePath := filepath.Join(dst, targetPath) if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } if item.FileInfo().IsDir() { err := os.MkdirAll(filePath, os.ModePerm) if err != nil { return err } continue } file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, item.Mode()) if err != nil { return err } fileInArchive, err := item.Open() if err != nil { return err } if _, err := io.Copy(file, fileInArchive); err != nil { return err } } return nil }