0
点赞
收藏
分享

微信扫一扫

Golang实现ZIP压缩与解压

之前分享了前端如何实现文件夹打包成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
}

举报

相关推荐

0 条评论