Skip to content

Instantly share code, notes, and snippets.

@bombsimon
Created January 23, 2020 09:34
Show Gist options
  • Save bombsimon/c45bfb034ceb29d49ee61d95cbaf5048 to your computer and use it in GitHub Desktop.
Save bombsimon/c45bfb034ceb29d49ee61d95cbaf5048 to your computer and use it in GitHub Desktop.
Create zip archive of files
package zip
import (
"archive/zip"
"io"
"os"
)
// Service represents a service that knows about compressing files into zip
// archives.
type Service struct{}
// New returns a new zip service.
func New() *Service {
return &Service{}
}
// ZipFiles compresses one or many files into a single zip archive file.
func (s *Service) ZipFiles(filename string, files []string) error {
newZipFile, err := os.Create(filename)
if err != nil {
return err
}
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
// Add files to zip
for _, file := range files {
if err := AddFileToZip(zipWriter, file); err != nil {
return err
}
}
return nil
}
// AddFileToZip takes a zip writer and a filename (path on disk) to include in
// the final zip file.
func AddFileToZip(zipWriter *zip.Writer, filename string) error {
fileToZip, err := os.Open(filename)
if err != nil {
return err
}
defer fileToZip.Close()
// Get the file information
info, err := fileToZip.Stat()
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
// 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.
header.Name = filename
// Change to deflate to gain better compression
// see http://golang.org/pkg/archive/zip/#pkg-constants
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, fileToZip)
return err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment