package zip import ( "archive/zip" "fmt" "io" "io/fs" "os" "strings" "git.sa-roci.de/oss/go_zipper" ) const ArchiveExt = ".zip" // NewZipper makes a new Zipper. func NewZipper(zipFilename string) zipper.Zipper { if !strings.HasSuffix(strings.ToLower(zipFilename), ArchiveExt) { zipFilename += ArchiveExt } z := zZipper{ Zipper: zipper.NewBaseZipper(zipFilename), } z.SetCompressor(z) return z } type zZipper struct { zipper.Zipper } func (z zZipper) OpenWriter(zipFile *os.File) error { z.SetWriter(zip.NewWriter(zipFile)) return nil } func (z zZipper) MultiFileSupported() bool { return true } func (z zZipper) Compress(fileToZip *os.File, pathInArchive string) (err error) { // Get the file information var info fs.FileInfo if info, err = fileToZip.Stat(); err != nil { return err } var header *zip.FileHeader if header, err = zip.FileInfoHeader(info); err != nil { return err } filename := info.Name() // Using FileInfoHeader() above only uses the basename of the file. If we want // to preserve the folder structure we can overwrite this with the full path. if len(pathInArchive) > 0 || strings.Contains(filename, "/") || strings.Contains(filename, "\\") { header.Name = zipper.PrependPath(filename, pathInArchive) } // Change to deflate to gain better compression // see http://golang.org/pkg/archive/zip/#pkg-constants header.Method = zip.Deflate if zipWriter, ok := z.GetWriter().(*zip.Writer); ok { var writer io.Writer if writer, err = zipWriter.CreateHeader(header); err != nil { return err } _, err = io.Copy(writer, fileToZip) } else { err = fmt.Errorf("unable to access compressor") } return }