Trabajo con archivos ZIP en Go (Golang)
En el desarrollo moderno con Go, a menudo surge la necesidad de trabajar con archivos — para empaquetar registros, distribuir configuraciones, realizar copias de seguridad o transferir datos entre microservicios. La biblioteca estándar de Go proporciona un paquete potente y flexible archive/zip que permite crear, leer y modificar archivos ZIP sin dependencias externas. En este artículo, analizaremos en detalle todos los aspectos del trabajo con archivos ZIP en Go.
Descripción general del paquete archive/zip
El paquete archive/zip forma parte de la biblioteca estándar de Go y admite:
- Lectura y escritura de archivos ZIP (formato PKWARE)
- Compresión mediante los métodos Deflate y Stored (sin compresión)
- Trabajo con archivos y directorios dentro del archivo
- Soporte para comentarios en el archivo y en archivos individuales
- Configuración de atributos de archivo (fecha, permisos)
- Procesamiento por flujo (los archivos pueden pesar gigabytes)
Tipos principales: zip.Writer para crear archivos y zip.Reader para leerlos.
Creación de un archivo ZIP
Para crear un archivo se utiliza zip.NewWriter, que recibe un io.Writer. Cada archivo se agrega mediante Create o CreateHeader.
package main
import ( "archive/zip" "bytes" "fmt" "io" "log" "os")
func main() { // Creamos un buffer para el archivo buf := new(bytes.Buffer) writer := zip.NewWriter(buf)
// Agregamos un archivo de texto 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) }
// Agregamos un archivo con subdirectorio 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) }
// Cerramos el writer obligatoriamente err = writer.Close() if err != nil { log.Fatal(err) }
// Guardamos el archivo en disco err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("Archivo creado: example.zip")}Lectura y extracción de archivos del archivo
Para leer un archivo se utiliza zip.NewReader, al que se le pasa un io.ReaderAt y el tamaño del archivo. Se puede leer tanto en memoria como por flujo.
func readArchive() { // Abrimos el archivo ZIP reader, err := zip.OpenReader("example.zip") if err != nil { log.Fatal(err) } defer reader.Close()
// Recorremos todos los archivos dentro del ZIP for _, file := range reader.File { fmt.Printf("Archivo: %s (tamaño: %d bytes)", file.Name, file.UncompressedSize64)
// Abrimos el archivo dentro del ZIP rc, err := file.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) }}Agregar archivos con metadatos
Con zip.FileHeader se pueden establecer la fecha, los permisos y el método de compresión:
func addFileWithMetadata(w *zip.Writer, name, content string) error { header := &zip.FileHeader{ Name: name, Method: zip.Deflate, // Usamos Deflate (compresión) } // Establecemos la hora de modificación header.SetModTime(time.Now()) // Establecemos los permisos (Unix rw-r--r--) header.SetMode(0644)
f, err := w.CreateHeader(header) if err != nil { return err } _, err = f.Write([]byte(content)) return También en la biblioteca
Procesamiento de JSON en PHP: funciones, ejemplos y mejores prácticas
Generador de códigos QR en TypeScript: la biblioteca qrcode y su uso
Generación de PDF en TypeScript: revisión de bibliotecas y herramientas