Trabalho com arquivos ZIP em Go (Golang): guia completo
No desenvolvimento moderno em Go (Golang), trabalhar com arquivos é uma das tarefas comuns. Seja para empacotar logs, fazer upload de arquivos para o servidor ou criar backups — a biblioteca padrão archive/zip fornece tudo o que é necessário para criar, ler e modificar arquivos ZIP sem instalar dependências de terceiros. Neste artigo, abordaremos as principais operações com ZIP em Go com exemplos práticos.
Principais recursos do pacote archive/zip
O pacote archive/zip faz parte da biblioteca padrão do Go e suporta:
- Criação de novos arquivos ZIP com estrutura de pastas arbitrária
- Leitura do conteúdo de arquivos existentes
- Extração de arquivos individuais ou de todo o arquivo
- Adição de arquivos a um arquivo existente (através de cópia)
- Trabalho com metadados de arquivos (data, permissões, comentários)
- Processamento em fluxo (sem carregar todo o arquivo na memória)
Criação de um arquivo ZIP em Go
Para criar um arquivo, usa-se zip.NewWriter(), que aceita um io.Writer. Isso permite gravar o arquivo tanto em um arquivo físico quanto em um buffer (por exemplo, para envio via HTTP).
package main
import ( "archive/zip" "bytes" "fmt" "io" "log" "os")
func createZip() { // Cria um buffer para o arquivo buf := new(bytes.Buffer) writer := zip.NewWriter(buf)
// Adiciona um arquivo com texto file1, err := writer.Create("hello.txt") if err != nil { log.Fatal(err) } _, err = file1.Write([]byte("Olá, mundo! Este é um arquivo do ZIP.")) if err != nil { log.Fatal(err) }
// Adiciona um arquivo em uma subpasta file2, err := writer.Create("docs/readme.md") if err != nil { log.Fatal(err) } _, err = file2.Write([]byte("# DocumentaçãoConteúdo do readme.")) if err != nil { log.Fatal(err) }
// Fecha o writer obrigatoriamente err = writer.Close() if err != nil { log.Fatal(err) }
// Salva o arquivo ZIP em disco err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("Arquivo criado: example.zip")}
func main() { createZip()}Leitura e extração de arquivos de um ZIP
Para ler um arquivo, usa-se zip.OpenReader() ou zip.NewReader() (para dados da memória). Cada arquivo é representado pela estrutura 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("Arquivo: %s (tamanho: %d bytes)", f.Name, f.UncompressedSize64)
// Abre o conteúdo do arquivo rc, err := f.Open() if err != nil { log.Fatal(err) }
// Lê o conteúdo content, err := io.ReadAll(rc) if err != nil { log.Fatal(err) } rc.Close()
fmt.Printf("Conteúdo: %s
", content) }}Extração de todos os arquivos para o disco
Frequentemente é necessário extrair um arquivo para um diretório especificado. É importante criar as subpastas corretamente.
func extractZip(src, dest string) { reader, err := zip.OpenReader(src) if err != nil { log.Fatal(err) } defer reader.Close()
for _, f := range reader.File { // Caminho para extração fpath := filepath.Join(dest, f.Name)
// Verifica se o caminho não sai do diretório dest (segurança) if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) { log.Fatalf("Caminho inválido: %s", fpath) }
// Cria as pastas if f.FileInfo Também na biblioteca
ORM para Kotlin: comparação e exemplos (Exposed, Ktorm, Hibernate)
Agendador de Tarefas em Node.js (node-cron, node-schedule, Bull)
Frameworks CLI para PHP: criando aplicações de console com Symfony Console e Laravel Zero
Humanizer para C# (.NET): guia completo com exemplos práticos
OpenSSL para C++: guia completo com exemplos