Sling Academy
Home/Golang/Handling Zip Archives Using the `archive/zip` Package in Go

Handling Zip Archives Using the `archive/zip` Package in Go

Last updated: November 26, 2024

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.

Next Article: Building In-Memory Lists with the `container/list` Package in Go

Previous Article: Parsing CSV Files with the `encoding/csv` Package in Go

Series: Working with Core package in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant