go - 创建没有标题的 zip 文件

标签 go zip

我有两个 zip,我使用 zip 命令来检查两个 zip 之间的区别, diff -y (unzip -l old.zip | psub) (unzip -l new.zip | psub) 我需要它们完全相同

首先在旧工具中创建,看起来像这样,没问题

 Length      Date    Time    Name                
---------  ---------- -----   ----              
      158         02-18-2018 12:26   META/MANI.MF        
      153         02-18-2018 12:26   META/mt.yaml        
  3956032         02-18-2018 12:26   ui/data.zip                    
---------                     -------       ---------                    
  3956343                     3 files                       

这是带有新工具的 zip,看起来不一样

  Length      Date    Time    Name              
---------  ---------- -----   ----               
|           0  02-18-2018 20:37           ./
|           0  02-18-2018 20:37           META/
|         150  02-18-2018 20:37           META/MANI.MF
>         178  02-18-2018 20:37           META/mt.yaml
>           0  02-18-2018 20:37           ui/
>     3980703  02-18-2018 20:37           ui/data.zip

如果我们查看 ui 文件夹(新工具的 zip),您会看到新工具中有两个条目

  ui/
  ui/data.zip

我只需要第二个,因为在旧工具中,文件结构应该相同

构建的逻辑是这样的

  1. during the program process I’ve folder which is called `ui’
  2. I zip it with the function Zipit(see code below) on the level so I’ve it like this root - ui - ui.zip
  3. then I remove the ui becouse I need just the zip and it contain a lot of files that not needed after the zip process
  4. create new empty folder ui os.MkdirAll(path, os.ModePerm)
  5. Mmove the zip inside the new ui folder - os.Rename(path+".zip", path+"/"+"data.zip")

我在这里做错了什么?我需要新的结构将在 zip 中完全相同

func Zipit(params ...string) error {


    zipfile, err := os.Create(params[1])
    if err != nil {
        return err
    }
    defer zipfile.Close()

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

    info, err := os.Stat(params[0])
    if err != nil {
        return nil
    }

    var baseDir string
    if info.IsDir(); len(params) > 2 {
        baseDir = params[2]
    } else {
        baseDir = filepath.Base(params[0])

    }

    filepath.Walk(params[0], 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(strings.TrimPrefix(path, params[0]))
        }

        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
}


to see the difference between the zip 

最佳答案

看起来您需要跳过向 zip 文件头添加目录,每次您在 filepath.Walk 回调中看到一个目录时,只需跳过它:

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

    // I moved this check to the beginning of the callback.
    if info.IsDir() {
        return nil
    }

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

    if baseDir != "" {
        header.Name = filepath.Join(strings.TrimPrefix(path, params[0]))
    }

    header.Method = zip.Deflate

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

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

关于go - 创建没有标题的 zip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48856557/

相关文章:

linux - Unix zip 命令正在更新现有存档而不是创建新存档

java.util.zip.ZipOutputStream - 更快地压缩大文件?

go - ioutil.TempFile 和 umask

go - 如何在golang中优雅地跳出select

go - 如何使用具有差异实现的函数接口(interface)

linux - Linux下如何分别压缩多个文件夹

java - 最小的合法 zip/jar 文件是什么?

xml - Go Parse XML to struct by tag 属性

python - 直接调用与 Python 子进程时 GOPATH 的解释不同

arrays - 在 scala 中,如何在 zip 两个数组后进行过滤