Working with ZIP Archives in Go (Golang): Creating, Reading, and Extracting Files

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): A Complete Guide



In modern Go (Golang) development, working with archives is a common task. Whether it's packaging logs, uploading files to a server, or creating backups — the standard library archive/zip provides everything needed to create, read, and modify ZIP archives without installing third-party dependencies. In this article, we'll cover the main operations with ZIP in Go with practical examples.



Key Features of the archive/zip Package

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

  • Creating new ZIP archives with arbitrary folder structures
  • Reading the contents of existing archives
  • Extracting individual files or entire archives
  • Adding files to an existing archive (via copying)
  • Working with file metadata (date, permissions, comments)
  • Stream processing (without loading the entire archive into memory)


Creating a ZIP Archive in Go

To create an archive, use zip.NewWriter(), which accepts an io.Writer. This allows writing the archive to a file or a buffer (e.g., for sending via HTTP).



package main

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

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

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

// Add a file in a subfolder file2, err := writer.Create("docs/readme.md") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte("# DocumentationReadme contents.")) if err != nil { log.Fatal(err) }

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

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

func main() { createZip()}


Reading and Extracting Files from ZIP

To read an archive, use zip.OpenReader() or zip.NewReader() (for in-memory data). Each file is represented by a zip.File struct.



func readZip() {    reader, err := zip.OpenReader("example.zip")    if err != nil {        log.Fatal(err)    }    defer reader.Close()

for _, f := range reader.File { fmt.Printf("File: %s (size: %d bytes)", f.Name, f.UncompressedSize64)

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

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

fmt.Printf("Contents: %s

", content) }}


Extracting All Files to Disk

Often you need to extract an archive to a specified directory. It's important to correctly create subfolders.



func extractZip(src, dest string) {    reader, err := zip.OpenReader(src)    if err != nil {        log.Fatal(err)    }    defer reader.Close()

for _, f := range reader.File { // Path for extraction fpath := filepath.Join(dest, f.Name)

// Check that the path does not escape dest (security) if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) { log.Fatalf("Invalid path: %s", fpath) }

// Create folders if f.FileInfo

Recommendations