Trabajo con archivos ZIP en Go (Golang): creación, lectura y extracción de archivos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Trabajo con archivos ZIP en Go (Golang): guía completa



En el desarrollo moderno con Go (Golang), trabajar con archivos comprimidos es una de las tareas comunes. Ya sea para empaquetar registros, cargar archivos al servidor o crear copias de seguridad, la biblioteca estándar archive/zip proporciona todo lo necesario para crear, leer y modificar archivos ZIP sin instalar dependencias de terceros. En este artículo, analizaremos las operaciones principales con ZIP en Go con ejemplos prácticos.



Funcionalidades principales del paquete archive/zip

El paquete archive/zip forma parte de la biblioteca estándar de Go y admite:

  • Creación de nuevos archivos ZIP con estructura de carpetas arbitraria
  • Lectura del contenido de archivos existentes
  • Extracción de archivos individuales o de todo el archivo
  • Adición de archivos a un archivo existente (mediante copia)
  • Trabajo con metadatos de archivos (fecha, permisos, comentarios)
  • Procesamiento en flujo (sin cargar todo el archivo en memoria)


Creación de un archivo ZIP en Go

Para crear un archivo se utiliza zip.NewWriter(), que recibe un io.Writer. Esto permite escribir el archivo tanto en un fichero como en un búfer (por ejemplo, para enviarlo por HTTP).



package main

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

func createZip() { // Creamos un búfer para el archivo buf := new(bytes.Buffer) writer := zip.NewWriter(buf)

// Añadimos un archivo con texto file1, err := writer.Create("hello.txt") if err != nil { log.Fatal(err) } _, err = file1.Write([]byte("¡Hola, mundo! Este es un archivo del ZIP.")) if err != nil { log.Fatal(err) }

// Añadimos un archivo en una subcarpeta file2, err := writer.Create("docs/readme.md") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte("# DocumentaciónContenido del readme.")) if err != nil { log.Fatal(err) }

// Cerramos el writer obligatoriamente err = writer.Close() if err != nil { log.Fatal(err) }

// Guardamos el archivo en un fichero err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("Archivo creado: example.zip")}

func main() { createZip()}


Lectura y extracción de archivos de un ZIP

Para leer un archivo se utiliza zip.OpenReader() o zip.NewReader() (para datos en memoria). Cada archivo está representado por la estructura zip.File.



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

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

// Abrimos el contenido del archivo rc, err := f.Open() if err != nil { log.Fatal(err) }

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

fmt.Printf("Contenido: %s

", content) }}


Extracción de todos los archivos al disco

A menudo es necesario descomprimir un archivo en un directorio específico. Es importante crear correctamente las subcarpetas.



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

for _, f := range reader.File { // Ruta para la extracción fpath := filepath.Join(dest, f.Name)

// Verificamos que la ruta no salga de dest (seguridad) if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) { log.Fatalf("Ruta no válida: %s", fpath) }

// Creamos las carpetas if f.FileInfo

Recommendations