go - 如何在 Go 中将文件压缩为没有目录文件夹的 .zip
问题描述
有一些关于在 Go 中将文件压缩为 .zip 的示例。但是,它们生成的文件包括目录文件夹。当我解压 .zip 文件时,会有一个新文件夹。
那么,如何在不包含目录文件夹的情况下将文件压缩为 .zip?
一个例子:
https://golangcode.com/create-zip-files-in-go/
package main
import (
"archive/zip"
"fmt"
"io"
"os"
)
func main() {
// List of Files to Zip
files := []string{"example.csv", "data.csv"}
output := "done.zip"
if err := ZipFiles(output, files); err != nil {
panic(err)
}
fmt.Println("Zipped File:", output)
}
// ZipFiles compresses one or many files into a single zip archive file.
// Param 1: filename is the output zip file's name.
// Param 2: files is a list of files to add to the zip.
func ZipFiles(filename string, files []string) error {
newZipFile, err := os.Create(filename)
if err != nil {
return err
}
defer newZipFile.Close()
zipWriter := zip.NewWriter(newZipFile)
defer zipWriter.Close()
// Add files to zip
for _, file := range files {
if err = AddFileToZip(zipWriter, file); err != nil {
return err
}
}
return nil
}
func AddFileToZip(zipWriter *zip.Writer, filename string) error {
fileToZip, err := os.Open(filename)
if err != nil {
return err
}
defer fileToZip.Close()
// Get the file information
info, err := fileToZip.Stat()
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
// Using FileInfoHeader() above only uses the basename of the file. If we want
// to preserve the folder structure we can overwrite this with the full path.
header.Name = filename
// Change to deflate to gain better compression
// see http://golang.org/pkg/archive/zip/#pkg-constants
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, fileToZip)
return err
}
解决方案
只需在 zip 标头中使用文件的基本名称即可。
header.Name = filepath.Base(filename)
^^^^^^^^^^^^^^
这是一个做同样事情的版本
package main
import (
"archive/zip"
"io"
"log"
"os"
"path/filepath"
)
func createFlatZip(w io.Writer, files ...string) error {
z := zip.NewWriter(w)
for _, file := range files {
src, err := os.Open(file)
if err != nil {
return err
}
info, err := src.Stat()
if err != nil {
return err
}
hdr, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
hdr.Name = filepath.Base(file) // Write only the base name in the header
dst, err := z.CreateHeader(hdr)
if err != nil {
return err
}
_, err = io.Copy(dst, src)
if err != nil {
return err
}
src.Close()
}
return z.Close()
}
func main() {
if len(os.Args) < 3 {
log.Fatalf("archive name and at least one file are required")
}
a, err := os.Create(os.Args[1])
if err != nil {
log.Fatal(err)
}
defer a.Close()
err = createFlatZip(a, os.Args[2:]...)
if err != nil {
log.Fatal(err)
}
}
结果:
~/src/gozip ➜ 去建造 ~/src/gozip ➜ mkdir test && echo 1 > test/1.txt # 在子文件夹中创建一个测试文件 ~/src/gozip ➜ ./gozip 1.zip 测试/1.txt ~/src/gozip ➜ 解压 -l 1.zip 存档:1.zip 长度 日期 时间 名称 --------- ---------- ----- ---- 2 2019 年 8 月 15 日 01:29 1.txt --------- ----- 2 1 个文件
推荐阅读
- c# - 从 .net 程序集中获取类型返回无法解析对程序集“System.Runtime,Version=4.2.1.0”的依赖
- objective-c - NSDictionary 中的值在被删除时是否被释放?
- selenium - “组件未初始化”nsresult:Selenium GeckoDriver 和 Mozilla 出现“0xc1f30001 (NS_ERROR_NOT_INITIALIZED)”错误
- c++ - 如何仅显示文件中的一个帐户?
- c# - Unity 2d 自上而下 RPG 风格,如何使用图层顺序排序处理瓷砖地图
- python - 如何在 Keras 中对简历段进行分类?
- c# - 从 Razor 页面中的数据库模型填充 TreeView
- graphql - 无法返回 null 或不可为 null 的字段 User.Role 无法从 prisma 突变中检索关系数据
- python - Matplotlib 使用滑块滚动图表时更新图表的更有效方式?
- javascript - 如何在其中插入一个javascript变量