Golang Zip压缩解压
Go (Golang) 与许多其他编程语言一样,直接从标准库中支持 zip 压缩。在本文中,我们将了解如何在 Go (Golang) 中创建 zip 存档,以及如何将一个或多个文件添加到 zip 存档中。我们还可以在同一个 zip 存档中创建文件夹,这在某些情况下很有用。
使用 zip 存档时,Go (Golang) 标准库中有一个名为 “archive/zip”的包。该包的目的是为创建和读取 zip 文件档案提供支持。
创建 zip 存档文件
您可能要做的第一件事是将存档创建为一个简单文件,就像处理 Go (Golang) 中的任何其他文件一样。使用 Go os 包 和 os.Create 函数
func Create(name string) (*File, error)
Create 创建或截断指定文件。如果文件已存在,则会被截断。如果该文件不存在,则使用模式 0666(在 umask 之前)创建该文件。如果成功,返回的 File 上的方法可用于 I/O;关联的文件描述符的模式为 O_RDWR。如果有错误,则其类型为 *PathError。
初始化 zip 存档 zip.Writer
在 archive/zip 包中,您将需要使用 zip.NewWriter 函数,该函数将用于将数据(文件和目录)写入最终的 zip 存档。
func NewWriter(w io.Writer) *Writer
NewWriter 返回一个新的 Writer,将 zip 文件写入 w。
使用 zip.Writer.Create 将文件添加到存档
创建 zip 编写器后,您可以将文件或目录添加到 zip 存档中。通过使用 zip.Writer.Create 函数
func (w *Writer) Create(name string) (io.Writer, error)
创建使用提供的名称将文件添加到 zip 文件中。它返回一个 Writer,文件内容应写入其中。文件内容将使用 Deflate 方法进行压缩。该名称必须是相对路径:不能以驱动器号(例如 C:)或前导斜杠开头,并且只允许使用正斜杠。要创建目录而不是文件,请在名称中添加尾部斜杠。在下次调用 Create、CreateHeader 或 Close 之前,必须将文件的内容写入 io.Writer。
使用 io.Copy 或 io.Writer.Write 写入文件内容
zip.Writer.Create 返回一个 可用于写入数据的 io.Writer ,因此任何文件内容都可以通过使用io.Copy 或仅从 io 调用 Write 函数来流式传输并写入该 writer。作家
func Copy(dst Writer, src Reader) (written int64, err error)
将副本从 src 复制到 dst,直到 src 达到 EOF 或发生错误。它返回复制的字节数以及复制时遇到的第一个错误(如果有)。
使用 zip.Writer.Close 关闭 zip 存档
将所有文件和目录写入存档后,您可以通过在 zip 存档上使用 zip.Writer.Close 方法来关闭 zip writer 并完成 您的 zip 存档,该方法会将所有数据写入底层数据流。
func (w *Writer) Close() error
Close 通过写入中心目录来完成 zip 文件的写入。它不会关闭底层编写器。
代码示例
在此代码示例中,我们尝试将 2 个文件(1 个 txt 文件和 1 个 csv 文件)归档到一个 zip 归档文件中。这些文件被存档在存档本身的不同子目录中。
package main
import (
"archive/zip"
"fmt"
"io"
"os"
)
func main() {
fmt.Println("creating zip archive...")
archive, err := os.Create("archive.zip")
if err != nil {
panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
fmt.Println("opening first file...")
f1, err := os.Open("test.csv")
if err != nil {
panic(err)
}
defer f1.Close()
fmt.Println("writing first file to archive...")
w1, err := zipWriter.Create("csv/test.csv")
if err != nil {
panic(err)
}
if _, err := io.Copy(w1, f1); err != nil {
panic(err)
}
fmt.Println("opening second file")
f2, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer f2.Close()
fmt.Println("writing second file to archive...")
w2, err := zipWriter.Create("txt/test.txt")
if err != nil {
panic(err)
}
if _, err := io.Copy(w2, f2); err != nil {
panic(err)
}
fmt.Println("closing zip archive...")
zipWriter.Close()
}
输出以下内容
creating zip archive...
opening first file...
writing first file to archive...
opening second file
writing second file to archive...
closing zip archive...
最终的 zip 存档包含预期的文件
$ unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
57 00-00-1980 00:00 csv/test.csv
12 00-00-1980 00:00 txt/test.txt
--------- -------
69 2 files
评论