创建存档排除基础目录

时间:2018-02-18 14:03:02

标签: go

我的目录中有很多我需要压缩的文件,我找到了这个 https://github.com/mholt/archiver操作系统 我需要的是在归档时排除基础目录,我没有在文档中找到这个

即仅压缩文件夹内没有父文件夹的文件

我使用的代码如下

err := archiver.Zip.Make(“mydir.zip", []string{path2Dir})

我该怎么做?

如果有其他好的解决方案,请告诉我

1 个答案:

答案 0 :(得分:0)

archiver库总是将baseDir附加到标题名称。请参阅zip.go的第111行。我没有在这里看到一个选项来使用这个库而无需修改以满足您的需求。

此库内部使用archive/zip。我修改了ziping代码以满足您的要求。希望代码是自我解释的。

package main

import (
    "archive/zip"
    "fmt"
    "os"

    "path/filepath"
    "strings"
    "path"
    "io"
)

var compressedFormats = map[string]struct{}{
    ".7z":   {},
    ".avi":  {},
    ".bz2":  {},
    ".cab":  {},
    ".gif":  {},
    ".gz":   {},
    ".jar":  {},
    ".jpeg": {},
    ".jpg":  {},
    ".lz":   {},
    ".lzma": {},
    ".mov":  {},
    ".mp3":  {},
    ".mp4":  {},
    ".mpeg": {},
    ".mpg":  {},
    ".png":  {},
    ".rar":  {},
    ".tbz2": {},
    ".tgz":  {},
    ".txz":  {},
    ".xz":   {},
    ".zip":  {},
    ".zipx": {},
}

func Zip(source, ou string) error {
    out, err := os.Create(ou)
    if err != nil {
        return fmt.Errorf("error creating %s: %v", ou, err)
    }
    defer out.Close()
    // Create a new zip archive.
    w := zip.NewWriter(out)
    sourceInfo, err := os.Stat(source)
    if err != nil {
        return fmt.Errorf("%s: stat: %v", source, err)
    }
    defer w.Close()
    var baseDir string
    if sourceInfo.IsDir() {
        baseDir = filepath.Base(source)
    }

    return filepath.Walk(source, func(fpath string, info os.FileInfo, err error) error {
        if baseDir == fpath {
            //skip the base diectory
            return nil
        }
        if err != nil {
            return fmt.Errorf("walking to %s: %v", fpath, err)
        }

        header, err := zip.FileInfoHeader(info)
        if err != nil {
            return fmt.Errorf("%s: getting header: %v", fpath, err)
        }

        if baseDir != "" {
            name, err := filepath.Rel(source, fpath)
            if err != nil {
                return err
            }
            header.Name = filepath.ToSlash(name)
        }

        if info.IsDir() {
            header.Name += "/"
            header.Method = zip.Store
        } else {
            ext := strings.ToLower(path.Ext(header.Name))
            if _, ok := compressedFormats[ext]; ok {
                header.Method = zip.Store
            } else {
                header.Method = zip.Deflate
            }
        }

        writer, err := w.CreateHeader(header)
        if err != nil {
            return fmt.Errorf("%s: making header: %v", fpath, err)
        }

        if info.IsDir() {
            return nil
        }

        if header.Mode().IsRegular() {
            file, err := os.Open(fpath)
            if err != nil {
                return fmt.Errorf("%s: opening: %v", fpath, err)
            }
            defer file.Close()

            _, err = io.CopyN(writer, file, info.Size())
            if err != nil && err != io.EOF {
                return fmt.Errorf("%s: copying contents: %v", fpath, err)
            }
        }
        return nil
    })
}

func main() {
    err := Zip("caddy", "result.zip")
    if err != nil {
        fmt.Println(err.Error())
    }
}