在Go中处理ZIP压缩包:archive/zip包完全指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

在Go (Golang) 中处理ZIP压缩包



在现代Go开发中,经常需要处理压缩包——用于打包日志、分发配置、备份或在微服务之间传输数据。Go标准库提供了强大且灵活的archive/zip包,无需第三方依赖即可创建、读取和修改ZIP压缩包。本文将详细讲解在Go中处理ZIP压缩包的所有方面。



archive/zip包概述



archive/zip包是Go标准库的一部分,支持:

  • 读取和写入ZIP压缩包(PKWARE格式)
  • 使用Deflate和Stored(无压缩)方法进行压缩
  • 处理压缩包内的文件和目录
  • 支持压缩包和单个文件的注释
  • 设置文件属性(日期、权限)
  • 流式处理(压缩包大小可达数GB)


主要类型:用于创建压缩包的zip.Writer和用于读取的zip.Reader。



创建ZIP压缩包



创建压缩包使用zip.NewWriter,它接受一个io.Writer。每个文件通过Create或CreateHeader添加。



package main

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

func main() { // 创建压缩包缓冲区 buf := new(bytes.Buffer) writer := zip.NewWriter(buf)

// 添加文本文件 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) }

// 添加带子目录的文件 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) }

// 必须关闭writer err = writer.Close() if err != nil { log.Fatal(err) }

// 将压缩包保存到磁盘 err = os.WriteFile("example.zip", buf.Bytes(), 0644) if err != nil { log.Fatal(err) } fmt.Println("压缩包已创建: example.zip")}


读取和提取压缩包中的文件



读取压缩包使用zip.NewReader,需要传入io.ReaderAt和压缩包大小。可以读取到内存中,也可以流式处理。



func readArchive() {    // 打开压缩包文件    reader, err := zip.OpenReader("example.zip")    if err != nil {        log.Fatal(err)    }    defer reader.Close()

// 遍历压缩包中的所有文件 for _, file := range reader.File { fmt.Printf("文件: %s (大小: %d 字节)", file.Name, file.UncompressedSize64)

// 打开压缩包内的文件 rc, err := file.Open() if err != nil { log.Fatal(err) }

// 读取内容 content, err := io.ReadAll(rc) if err != nil { log.Fatal(err) } rc.Close()

fmt.Printf("内容: %s

", content) }}


添加带元数据的文件



使用zip.FileHeader可以设置日期、权限和压缩方法:



func addFileWithMetadata(w *zip.Writer, name, content string) error {    header := &zip.FileHeader{        Name:   name,        Method: zip.Deflate, // 使用Deflate(压缩)    }    // 设置修改时间    header.SetModTime(time.Now())    // 设置权限(Unix rw-r--r--)    header.SetMode(0644)

f, err := w.CreateHeader(header) if err != nil { return err } _, err = f.Write([]byte(content)) return

推荐