Working with zip archives is a common task for developers, whether it's for compressing files, creating backups, or distributing multiple files as a single package. In Go, the archive/zip package provides solid functionality to handle zip files efficiently. This article will guide you through creating and extracting zip files using this package.
Creating a Zip Archive
To create a zip archive, you'll need to initiate a new zip writer and add files to it. Below is a step-by-step guide to creating a zip file using the archive/zip package:
Step-by-Step Code Example
package main
import (
"archive/zip"
"fmt"
"io"
"log"
"os"
)
func main() {
// Creating a zip file
zipFile, err := os.Create("example.zip")
if err != nil {
log.Fatal(err)
}
defer zipFile.Close()
// Creating a zip writer
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
// List of files to add to the zip
files := []string{"file1.txt", "file2.txt"}
for _, file := range files {
addFileToZip(zipWriter, file)
}
}
// Function to add a file to the zip archive
func addFileToZip(zipWriter *zip.Writer, filename string) {
fileToZip, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
defer fileToZip.Close()
// Getting file information
info, err := fileToZip.Stat()
if err != nil {
log.Fatal(err)
}
// Creating a zip header from the file info
header, err := zip.FileInfoHeader(info)
if err != nil {
log.Fatal(err)
}
// Using the filename for the header name
header.Name = filename
// Creating a writer for the header
writer, err := zipWriter.CreateHeader(header)
if err != nil {
log.Fatal(err)
}
// Copying the file content to the zip
_, err = io.Copy(writer, fileToZip)
if err != nil {
log.Fatal(err)
}
}Extracting a Zip Archive
Let’s move on to extracting files from a zip archive. You’ll require reading the zip file and extracting its contents to a desired location on your filesystem. Here’s how you can accomplish this using archive/zip:
Step-by-Step Code Example
package main
import (
"archive/zip"
"fmt"
"io"
"log"
"os"
"path/filepath"
)
func main() {
zipPath := "example.zip"
destination := "output_folder"
// Opening the zip file
zipReader, err := zip.OpenReader(zipPath)
if err != nil {
log.Fatal(err)
}
defer zipReader.Close()
// Iterating through each file in the archive
for _, file := range zipReader.File {
fmt.Println("Extracting", file.Name)
// Creating the full path for the file
filePath := filepath.Join(destination, file.Name)
outputFile(file, filePath)
}
}
// Function to output an individual file
func outputFile(zf *zip.File, filePath string) {
// Creating directories if necessary
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
log.Fatal(err)
}
// Creating the output file
fileWriter, err := os.Create(filePath)
if err != nil {
log.Fatal(err)
}
defer fileWriter.Close()
// Opening the zip file for reading
src, err := zf.Open()
if err != nil {
log.Fatal(err)
}
defer src.Close()
// Copying data from zip to the output file
_, err = io.Copy(fileWriter, src)
if err != nil {
log.Fatal(err)
}
}Conclusion
The archive/zip package simplifies working with zip archives significantly. Creating and extracting zip files are the two most common operations that you can easily perform by following the steps and code examples discussed above. This package is very powerful and can be integrated into larger systems to help manage file organization and distribution effectively.