go - 解压具有不同名称的工件

标签 go

我有一个程序,我需要在其中将文件夹内容(从 folder1)复制到同一目录级别(路径)中的新文件夹(folder2)。 因为我不能给出相同的名称,所以我使用 tmpFolder 名称(对于 folder2)。 当我完成所有逻辑后,我需要压缩复制的文件夹 我给 zip 命名为 folder1.zip 问题是当我提取 folder1.zip 我看到 folder2

我希望它在压缩后成为 folder1

我可以使用一些技巧来做到这一点吗?

此外,我知道我可以复制到不同级别(路径)的 folder2 但我想尽可能避免它,因为 在处理大文件夹内容时,副本可能非常昂贵。

我使用这段代码来压缩文件夹:

func Zipit(source, target string) error {
    zipfile, err := os.Create(target)
    if err != nil {
        return err
    }
    defer zipfile.Close()

    archive := zip.NewWriter(zipfile)
    defer archive.Close()

    info, err := os.Stat(source)
    if err != nil {
        return nil
    }

    var baseDir string
    if info.IsDir() {
        baseDir = filepath.Base(source)
    }

    filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        header, err := zip.FileInfoHeader(info)
        if err != nil {
            return err
        }

        if baseDir != "" {
            header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
        }

        if info.IsDir() {
            header.Name += "/"
        } else {
            header.Method = zip.Deflate
        }

        writer, err := archive.CreateHeader(header)
        if err != nil {
            return err
        }

        if info.IsDir() {
            return nil
        }

        file, err := os.Open(path)
        if err != nil {
            return err
        }
        defer file.Close()
        _, err = io.Copy(writer, file)
        return err
    })

    return err
}

最佳答案

zip 存档中的文件和目录名称来自 zip.FileHeader .

您的代码已经从 os.FileInfo 初始化了 header .这很重要,因为它会填充元数据,例如时间戳和未压缩的大小。

此外,您的代码似乎在执行以下操作:

如果调用:

Zipit("/path/to/folder2/", "/path/to/folder1.zip")

在遍历目录树之前,它计算基本目录:

baseDir = filepath.Base(source)
// baseDir is "folder2"

然后对于每个文件,存档内的路径设置为:

header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))

这会将诸如 /path/to/folder2/otherdir/myfile 之类的文件名转换为 folder2/otherdir/myfile

如果要更改存储在存档中的目录名称,只需将 baseDir 更改为所需的名称即可。

我推荐以下解决方案:

将函数签名更改为:

func Zipit(source, target, newBaseName string) error {

将 basedir 更改为:

if newBaseName != "" {
    baseDir = newBaseName
else if info.IsDir() {
    baseDir = filepath.Base(source)
}

然后调用你的函数:

Zipit("/path/to/folder2/", "/path/to/folder1.zip", "folder1")

这应该会生成一个存档,该存档会提取到 folder1/ 中。

关于go - 解压具有不同名称的工件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48732412/

相关文章:

functional-programming - go-lang curry 怎么做?

go - 使用golang.org/x/text/currency中的currency.Symbol在Golang中使用货币格式

search - 如何通过基本名称(不带扩展名)检查文件是否存在?

php - 仅带有脚本标签的 HTML 文件

go - 谁能帮我解决这个 GoLand 终端错误

json - 在go中解码json时调整结构

go - 如何使用第三方包中未导出的对象作为 golang 中的返回类型?

email - 在 GO 中使用代理后面的 SMTP/电子邮件客户端

go - 如何在 GO 中连接到 GCE 中的客户端

go - 如何将目录[不仅仅是其中的文件]写入golang中的tar.gz文件