之前分享了前端如何实现文件夹打包成zip压缩包并上传,这里将分享Golang如何实现本地文件夹的zip压缩打包、与zip文件解压。得益于Golang的官方库“archive/zip”,就能轻松搞定。下面直接上干货。
压缩
// dir: 需要打包的本地文件夹路径
// dst: 保存压缩包的本地路径
func compressDir(dir string, dst string) error {
zipFile, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE, 0660)
if err != nil {
return err
}
defer zipFile.Close()
archive := zip.NewWriter(zipFile)
defer archive.Close()
return filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if path == dir {
return nil
}
info, _ := d.Info()
h, _ := zip.FileInfoHeader(info)
h.Name = strings.TrimPrefix(path, dir+"/")
if info.IsDir() {
h.Name += "/"
} else {
h.Method = zip.Deflate
}
writer, _ := archive.CreateHeader(h)
if !info.IsDir() {
srcFile, _ := os.Open(path)
defer srcFile.Close()
io.Copy(writer, srcFile)
}
return nil
})
}
解压
// src: 需要解压的zip文件
func decompressZip(src string) error {
archive, err := zip.OpenReader(src)
if err != nil {
return err
}
dir := filepath.Dir(src)
defer archive.Close()
for _, f := range archive.File {
filePath := filepath.Join(dir, f.Name)
if f.FileInfo().IsDir() {
os.MkdirAll(filePath, os.ModePerm)
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return fmt.Errorf("failed to make directory (%v)", err)
}
dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return fmt.Errorf("failed to create file (%v)", err)
}
fileInArchive, err := f.Open()
if err != nil {
return fmt.Errorf("failed to open file in zip (%v)", err)
}
if _, err := io.Copy(dstFile, fileInArchive); err != nil {
return fmt.Errorf("failed to copy file in zip (%v)", err)
}
dstFile.Close()
fileInArchive.Close()
}
return nil
}