package utils import ( "archive/zip" "io" "os" "path/filepath" "strings" ) func Zip(source, zipPath string) error { archiveFile, err := os.Create(zipPath) if err != nil { return err } defer archiveFile.Close() archive := zip.NewWriter(archiveFile) defer archive.Close() info, err := os.Stat(source) if err != nil { return nil } var baseDir string if info.IsDir() { baseDir = filepath.Base(source) } return filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if !info.IsDir() || !info.Mode().IsRegular() { return nil } header, err := zip.FileInfoHeader(info) if err != nil { return err } if baseDir != "" { header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := archive.CreateHeader(header) if err != nil { return err } if info.IsDir() { return nil } file, err := os.Open(path) if err != nil { return err } defer file.Close() _, err = io.Copy(writer, file) return err }) } func Unzip(zipPath, target string) error { reader, err := zip.OpenReader(zipPath) if err != nil { return err } if err := os.MkdirAll(target, 0755); err != nil { return err } for _, file := range reader.File { path := filepath.Join(target, file.Name) if file.FileInfo().IsDir() { os.MkdirAll(path, file.Mode()) continue } fileReader, err := file.Open() if err != nil { if fileReader != nil { fileReader.Close() } return err } targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) if err != nil { fileReader.Close() if targetFile != nil { targetFile.Close() } return err } if _, err := io.Copy(targetFile, fileReader); err != nil { fileReader.Close() targetFile.Close() return err } fileReader.Close() targetFile.Close() } return nil }