Working with ZIP Archives in Go: A Complete Guide to the archive/zip Package

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Working with ZIP Archives in Go (Golang)



In modern Go development, the need to work with archives often arises — for packaging logs, distributing configurations, backups, or transferring data between microservices. The Go standard library provides a powerful and flexible package archive/zip that allows you to create, read, and modify ZIP archives without third-party dependencies. In this article, we will thoroughly cover all aspects of working with ZIP archives in Go.



Overview of the archive/zip Package



The archive/zip package is part of the Go standard library and supports:

  • Reading and writing ZIP archives (PKWARE format)
  • Compression using Deflate and Stored (no compression) methods
  • Working with files and directories inside the archive
  • Support for archive and individual file comments
  • Setting file attributes (date, permissions)
  • Streaming processing (archives can be gigabytes in size)


Main types: zip.Writer for creating archives and zip.Reader for reading.



Creating a ZIP Archive



To create an archive, use zip.NewWriter, which accepts an io.Writer. Each file is added via Create or CreateHeader.



package main

import ( "archive/zip" "bytes" "fmt" "io" "log" "os")

func main() { // Create a buffer for the archive buf := new(bytes.Buffer) writer := zip.NewWriter(buf)

// Add a text file file1, err := writer.Create("hello.txt") if err != nil { log.Fatal(err) } _, err = file1.Write([]byte("Hello, Go ZIP!")) if err != nil { log.Fatal(err) }

// Add a file with a subdirectory file2, err := writer.Create("config/settings.json") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte(`{"version": 1, "debug": true}`)) if err != nil { log.Fatal(err) }

// Must close the writer err = writer.Close() if err != nil { log.Fatal(err) }

// Save the archive to disk err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("Archive created: example.zip")}


Reading and Extracting Files from an Archive



To read an archive, use zip.NewReader, which takes an io.ReaderAt and the archive size. You can read both into memory and stream.



func readArchive() {    // Open the archive file    reader, err := zip.OpenReader("example.zip")    if err != nil {        log.Fatal(err)    }    defer reader.Close()

// Iterate over all files in the archive for _, file := range reader.File { fmt.Printf("File: %s (size: %d bytes)", file.Name, file.UncompressedSize64)

// Open the file inside the archive rc, err := file.Open() if err != nil { log.Fatal(err) }

// Read the content content, err := io.ReadAll(rc) if err != nil { log.Fatal(err) } rc.Close()

fmt.Printf("Content: %s

", content) }}


Adding Files with Metadata



Using zip.FileHeader, you can set the date, permissions, and compression method:



func addFileWithMetadata(w *zip.Writer, name, content string) error {    header := &zip.FileHeader{        Name:   name,        Method: zip.Deflate, // Use Deflate (compression)    }    // Set modification time    header.SetModTime(time.Now())    // Set permissions (Unix rw-r--r--)    header.SetMode(0644)

f, err := w.CreateHeader(header) if err != nil { return err } _, err = f.Write([]byte(content)) return

Recommendations