You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Go语言中递归压缩目录:排除父目录实现方案

在Go中实现压缩目录内容但不包含父目录的方法

嘿,我来帮你搞定这个需求!要实现压缩父目录下所有文件和文件夹但不包含父目录本身,咱们可以用Go标准库的archive/zip结合文件系统操作来完成,不用依赖第三方包,非常简洁。

核心思路

简单来说,就是遍历目标目录下的所有内容(包括子目录和文件),然后将这些内容以相对路径的形式添加到zip压缩包中,这样解压后就不会带上原来的父目录啦。

完整实现代码

package main

import (
	"archive/zip"
	"io"
	"os"
	"path/filepath"
)

// zipDirContents 压缩指定目录下的所有内容,但不包含目录本身
// srcDir: 要压缩的源目录路径
// destZip: 生成的zip文件路径
func zipDirContents(srcDir string, destZip string) error {
	// 先确保源目录是绝对路径,避免后续路径计算出错
	absSrcDir, err := filepath.Abs(srcDir)
	if err != nil {
		return err
	}

	// 创建目标zip文件
	zipFile, err := os.Create(destZip)
	if err != nil {
		return err
	}
	defer zipFile.Close()

	// 初始化zip写入器
	zipWriter := zip.NewWriter(zipFile)
	defer zipWriter.Close()

	// 遍历源目录下的所有文件和子目录
	err = filepath.Walk(absSrcDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 跳过源目录本身,只处理里面的内容
		if path == absSrcDir {
			return nil
		}

		// 计算当前文件/目录相对于源目录的路径,这是关键!
		relativePath, err := filepath.Rel(absSrcDir, path)
		if err != nil {
			return err
		}

		// 创建zip条目
		zipEntry, err := zipWriter.Create(relativePath)
		if err != nil {
			return err
		}

		// 如果是目录,直接返回(已经创建了目录条目)
		if info.IsDir() {
			return nil
		}

		// 如果是文件,读取内容并写入zip
		file, err := os.Open(path)
		if err != nil {
			return err
		}
		defer file.Close()

		_, err = io.Copy(zipEntry, file)
		return err
	})

	return err
}

func main() {
	// 示例:压缩./my-project目录下的所有内容,生成./project.zip
	err := zipDirContents("./my-project", "./project.zip")
	if err != nil {
		panic(err)
	}
}

关键细节说明

  • 相对路径计算:用filepath.Rel(absSrcDir, path)获取文件相对于源目录的路径,这样添加到zip里的条目就不会包含父目录名称,解压后文件直接在当前目录。
  • 跳过源目录本身:在遍历的时候判断如果当前路径是源目录,就直接跳过,避免把父目录也加进去。
  • 权限与目录处理:创建zip条目时会自动保留文件的基本权限,目录也会被正确创建为zip里的目录条目,解压后目录结构和原目录一致。

使用方法

你只需要调用zipDirContents函数,传入两个参数:

  • 第一个是要压缩的源目录路径(可以是相对路径或绝对路径)
  • 第二个是要生成的zip文件路径

比如你要压缩./docs目录的内容到./docs-backup.zip,就这么调用:

err := zipDirContents("./docs", "./docs-backup.zip")
if err != nil {
    // 处理错误,比如打印日志或返回错误信息
    log.Fatal(err)
}

测试一下:解压生成的zip文件,你会看到里面直接是docs目录下的所有文件和子目录,不会有docs这个父目录哦!

内容的提问来源于stack exchange,提问作者jenkelblankel

火山引擎 最新活动