Go (Golang) 中 ZIP/归档文件操作完全指南

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

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

开始课程

Go (Golang) 中 ZIP/归档文件操作



在 Go (Golang) 中,ZIP 归档的操作通过标准包 archive/zip 实现。该包提供了创建、读取、写入和从 ZIP 归档中提取文件所需的所有工具。与许多其他语言不同,Go 不需要安装第三方库即可执行基本操作——标准库中已包含所有功能。



archive/zip 包支持:

  • 创建新的 ZIP 归档
  • 读取现有归档
  • 添加文件和目录
  • 提取单个文件或整个归档
  • 处理文件元数据(日期、权限)


在 Go 中创建 ZIP 归档



要创建归档,需要以写入模式打开一个文件并创建一个 zip.Writer。每个文件通过 Create 或用于精细调整的 CreateHeader 添加。



package main

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

func main() { // 创建一个新的 ZIP 文件 zipFile, err := os.Create("example.zip") if err != nil { panic(err) } defer zipFile.Close()

// 为归档创建一个 Writer zipWriter := zip.NewWriter(zipFile) defer zipWriter.Close()

// 添加一个文本文件 file1, err := zipWriter.Create("hello.txt") if err != nil { panic(err) } _, err = file1.Write([]byte("Hello, Go ZIP!")) if err != nil { panic(err) }

// 添加第二个文件,内容来自现有文件 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("归档已创建: example.zip")}


读取 ZIP 归档



要读取归档,使用 zip.OpenReader,它返回一个 ReadCloser。每个文件由 zip.File 结构体表示。



package main

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

func main() { // 以读取模式打开归档 reader, err := zip.OpenReader("example.zip") if err != nil { panic(err) } defer reader.Close()

// 遍历归档中的所有文件 for _, file := range reader.File { fmt.Printf("文件: %s", file.Name) fmt.Printf("大小: %d 字节", file.UncompressedSize64) fmt.Printf("压缩后大小: %d 字节", file.CompressedSize64) fmt.Printf("修改日期: %s", file.Modified.Format("2006-01-02 15:04:05")) fmt.Println("---")

// 从归档中打开文件 rc, err := file.Open() if err != nil { panic(err) } defer rc.Close()

// 读取内容(如果是小文件) content, err := io.ReadAll(rc) if err != nil { panic(err) } fmt.Printf("内容: %s

", string(content)) }}


从归档中提取文件



要将归档完全解压到目录中,需要创建目标文件夹并写入每个文件的内容。



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 { // 安全的文件名(防止路径遍历) filePath := filepath.Join(dest, file.Name) // 检查是否超出目标目录范围 if !strings.HasPrefix(filepath.Clean(filePath),

推荐