Trabajo con archivos ZIP en Go (Golang)
En Go (Golang), el trabajo con archivos ZIP se implementa a través del paquete estándar archive/zip. Este paquete proporciona todas las herramientas necesarias para crear, leer, escribir y extraer archivos de archivos ZIP. A diferencia de muchos otros lenguajes, Go no requiere la instalación de bibliotecas de terceros para operaciones básicas; todo ya está en la biblioteca estándar.
El paquete archive/zip soporta:
- Creación de nuevos archivos ZIP
- Lectura de archivos existentes
- Adición de archivos y directorios
- Extracción de archivos individuales o de todo el archivo
- Trabajo con metadatos de archivos (fecha, permisos de acceso)
Creación de un archivo ZIP en Go
Para crear un archivo, es necesario abrir un archivo para escritura y crear un zip.Writer. Cada archivo se añade mediante Create o CreateHeader para una configuración detallada.
package main
import ( "archive/zip" "fmt" "io" "os")
func main() { // Creamos un nuevo archivo ZIP zipFile, err := os.Create("example.zip") if err != nil { panic(err) } defer zipFile.Close()
// Creamos un Writer para el archivo zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close()
// Añadimos un archivo de texto file1, err := zipWriter.Create("hello.txt") if err != nil { panic(err) } _, err = file1.Write([]byte("¡Hola, Go ZIP!")) if err != nil { panic(err) }
// Añadimos un segundo archivo con contenido de un archivo existente sourceFile, err := os.Open("source.txt") if err != nil { panic(err) } defer sourceFile.Close()
targetFile, err := zipWriter.Create("copy_of_source.txt") if err != nil { panic(err) } _, err = io.Copy(targetFile, sourceFile) if err != nil { panic(err) }
fmt.Println("Archivo creado: example.zip")}Lectura de un archivo ZIP
Para leer un archivo se utiliza zip.OpenReader, que devuelve un ReadCloser. Cada archivo está representado por la estructura zip.File.
package main
import ( "archive/zip" "fmt" "io" "os")
func main() { // Abrimos el archivo para lectura reader, err := zip.OpenReader("example.zip") if err != nil { panic(err) } defer reader.Close()
// Iteramos sobre todos los archivos en el archivo for _, file := range reader.File { fmt.Printf("Archivo: %s", file.Name) fmt.Printf("Tamaño: %d bytes", file.UncompressedSize64) fmt.Printf("Tamaño comprimido: %d bytes", file.CompressedSize64) fmt.Printf("Fecha de modificación: %s", file.Modified.Format("2006-01-02 15:04:05")) fmt.Println("---")
// Abrimos el archivo del archivo rc, err := file.Open() if err != nil { panic(err) } defer rc.Close()
// Leemos el contenido (si es un archivo pequeño) content, err := io.ReadAll(rc) if err != nil { panic(err) } fmt.Printf("Contenido: %s
", string(content)) }}Extracción de archivos de un archivo
Para descomprimir completamente un archivo en un directorio, es necesario crear las carpetas de destino y escribir el contenido de cada archivo.
package main
import ( "archive/zip" "fmt" "io" "os" "path/filepath")
func extractZip(src, dest string) error { reader, err := zip.OpenReader(src) if err != nil { return err } defer reader.Close()
for _, file := range reader.File { // Nombre de archivo seguro (prevención de path traversal) filePath := filepath.Join(dest, file.Name) // Verificación de que no se sale del directorio de destino if !strings.HasPrefix(filepath.Clean(filePath), También en la biblioteca
MassTransit C# (.NET): guía completa con ejemplos prácticos
Chalk para JavaScript (Node.js): guía completa con ejemplos
Caché en Swift (iOS/macOS): Redis, NSCache y otras soluciones
Event Bus y el patrón Observer en Rust: implementación de arquitectura basada en eventos