Travailler avec les archives ZIP en Go (Golang) : guide complet
Dans le développement moderne avec Go (Golang), la gestion des archives est une tâche courante. Qu'il s'agisse de compresser des logs, de télécharger des fichiers sur un serveur ou de créer des sauvegardes, la bibliothèque standard archive/zip fournit tout le nécessaire pour créer, lire et modifier des archives ZIP sans installer de dépendances tierces. Dans cet article, nous allons explorer les opérations de base avec ZIP en Go à l'aide d'exemples pratiques.
Fonctionnalités principales du paquet archive/zip
Le paquet archive/zip fait partie de la bibliothèque standard de Go et prend en charge :
- La création de nouvelles archives ZIP avec une structure de dossiers arbitraire
- La lecture du contenu d'archives existantes
- L'extraction de fichiers individuels ou de l'archive entière
- L'ajout de fichiers à une archive existante (par copie)
- La gestion des métadonnées des fichiers (date, droits d'accès, commentaires)
- Le traitement en flux (sans charger toute l'archive en mémoire)
Création d'une archive ZIP en Go
Pour créer une archive, on utilise zip.NewWriter(), qui accepte un io.Writer. Cela permet d'écrire l'archive aussi bien dans un fichier que dans un tampon (par exemple, pour l'envoyer via HTTP).
package main
import ( "archive/zip" "bytes" "fmt" "io" "log" "os")
func createZip() { // Création d'un tampon pour l'archive buf := new(bytes.Buffer) writer := zip.NewWriter(buf)
// Ajout d'un fichier avec du texte file1, err := writer.Create("hello.txt") if err != nil { log.Fatal(err) } _, err = file1.Write([]byte("Bonjour le monde ! Ceci est un fichier de l'archive ZIP.")) if err != nil { log.Fatal(err) }
// Ajout d'un fichier dans un sous-dossier file2, err := writer.Create("docs/readme.md") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte("# DocumentationContenu du readme.")) if err != nil { log.Fatal(err) }
// Fermeture obligatoire du writer err = writer.Close() if err != nil { log.Fatal(err) }
// Sauvegarde de l'archive dans un fichier err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("Archive créée : example.zip")}
func main() { createZip()}Lecture et extraction de fichiers depuis une archive ZIP
Pour lire une archive, on utilise zip.OpenReader() ou zip.NewReader() (pour des données en mémoire). Chaque fichier est représenté par une structure 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("Fichier : %s (taille : %d octets)", f.Name, f.UncompressedSize64)
// Ouverture du contenu du fichier rc, err := f.Open() if err != nil { log.Fatal(err) }
// Lecture du contenu content, err := io.ReadAll(rc) if err != nil { log.Fatal(err) } rc.Close()
fmt.Printf("Contenu : %s
", content) }}Extraction de tous les fichiers sur le disque
Il est souvent nécessaire de décompresser une archive dans un répertoire spécifique. Il est important de créer correctement les sous-dossiers.
func extractZip(src, dest string) { reader, err := zip.OpenReader(src) if err != nil { log.Fatal(err) } defer reader.Close()
for _, f := range reader.File { // Chemin d'extraction fpath := filepath.Join(dest, f.Name)
// Vérification que le chemin ne sort pas de dest (sécurité) if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) { log.Fatalf("Chemin non autorisé : %s", fpath) }
// Création des dossiers if f.FileInfo Aussi dans la bibliothèque
Files d'attente de tâches en Swift : GCD, OperationQueue et Combine pour iOS/macOS
Envoi d'email en Kotlin : bibliothèques et exemples de code
Configuration d'applications C++ : bibliothèques et outils pour un réglage flexible
Travailler avec CSV en PHP : la bibliothèque PhpSpreadsheet