Go 解压缩具有不同名称的工件

Go 解压缩具有不同名称的工件,go,Go,我有一个程序,需要将文件夹内容从folder1复制到同一目录级路径中的新文件夹folder2。 因为我不能给出相同的名称,所以我对folder2使用tmpFolder名称。 当我完成所有的逻辑,我需要压缩复制的文件夹 我给拉链取名为folder1.zip 问题是当我提取folder1.zip时 我明白了 我希望它在拉链后折叠起来 有什么技巧我可以用吗 此外,我知道我可以复制到不同级别路径中的folder2,但如果可能的话,我想避免它,因为 在处理大文件夹内容时,副本可能非常昂贵 我使用以下代码压

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

我希望它在拉链后折叠起来

有什么技巧我可以用吗

此外,我知道我可以复制到不同级别路径中的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归档中的文件和目录的名称来自

您的代码已从中初始化标头。这很重要,因为它会填充元数据,如时间戳和未压缩大小

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

如果使用以下命令调用:

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/

的归档文件。您可以将header.Name更改为您想要的任何名称,这是归档文件中的文件名。这被设置为zip.FileInfoHeaderinfo中的文件名。@Marc-你能写下它应该在哪里吗?是这样的名称:=info.Nametest header,err:=zip.FileInfoHeadername吗?您希望保留FileInfoHeader,因为它还设置其他字段时间戳、大小等。。。但是部分代码已经更改了header.Name。您只需要将路径中的folder2替换为folder1。或者更简单:在filepath之前将baseDir更改为folder1。marc,最后一件事是,有时我需要使用带有2个参数的zipit方法,有时像您那样使用3个参数,您会怎么做?您不会,Go不允许多个函数签名。您可以选择上面保留旧行为的建议为newBaseName为空,也可以创建帮助函数。请查看是否可以提供帮助