package gzip import ( "compress/gzip" "fmt" "io" "io/fs" "os" "strings" zipper "git.sa-roci.de/oss/go_zipper" ) const ArchiveExt = ".gz" // NewZipper makes a new Zipper. func NewGZipper(gzipFilename string, multiFile bool) zipper.Zipper { if !strings.HasSuffix(strings.ToLower(gzipFilename), ArchiveExt) { gzipFilename += ArchiveExt } gzipper := gZipper{ Zipper: zipper.NewBaseZipper(gzipFilename), multiFile: multiFile, } gzipper.SetCompressor(&gzipper) return gzipper } type gZipper struct { zipper.Zipper output io.Writer multiFile bool } func (gz *gZipper) OpenWriter(zipFile *os.File) error { gz.SetWriter(gzip.NewWriter(zipFile)) gz.output = zipFile return nil } func (gz *gZipper) MultiFileSupported() bool { return gz.multiFile } func (gz *gZipper) 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 } filename := info.Name() if writer, ok := gz.GetWriter().(*gzip.Writer); ok { writer.ModTime = info.ModTime() // 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, "\\") { writer.Name = zipper.PrependPath(filename, pathInArchive) } else { writer.Name = filename } if _, err = io.Copy(writer, fileToZip); err == nil { flushErr := writer.Flush() if err = writer.Close(); err != nil { err = flushErr } else { writer.Reset(gz.output) } } } else { err = fmt.Errorf("unable to access compressor") } return }