Golang - 压缩一个包含空子目录和文件的目录

Golang - Zip a directory which includes empty subdirectory and files

我正在尝试压缩一个现有目录,该目录也有一些空子目录。

这是文件夹结构。

parent/
├── child
│   └── child.txt
├── empty-folder
└── parent.txt

2 directories, 2 files

这是源代码。它写入所有包含文件的子目录。但是它跳过了一个空的子目录。有没有办法在 zip 文件中也添加一个空子目录?提前致谢。

package main

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

// check for error and stop the execution
func checkForError(err error) {
    if err != nil {
        fmt.Println("Error - ", err)
        os.Exit(1)
    }
}

const (
    ZIP_FILE_NAME    = "example.zip"
    MAIN_FOLDER_NAME = "parent"
)

// Main function
func main() {

    var targetFilePaths []string

    // get filepaths in all folders
    err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
        if info.IsDir() {
            return nil
        }
        // add all the file paths to slice
        targetFilePaths = append(targetFilePaths, path)
        return nil
    })
    checkForError(err)

    // zip file logic starts here
    ZipFile, err := os.Create(ZIP_FILE_NAME)
    checkForError(err)
    defer ZipFile.Close()

    zipWriter := zip.NewWriter(ZipFile)
    defer zipWriter.Close()

    for _, targetFilePath := range targetFilePaths {

        file, err := os.Open(targetFilePath)
        checkForError(err)
        defer file.Close()

        // create path in zip
        w, err := zipWriter.Create(targetFilePath)
        checkForError(err)

        // write file to zip
        _, err = io.Copy(w, file)
        checkForError(err)

    }

}

要写入一个空目录,您只需调用 Create 并使用带有尾随路径分隔符的目录路径。

package main

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

const (
    ZIP_FILE_NAME    = "example.zip"
    MAIN_FOLDER_NAME = "parent"
)

type fileMeta struct {
    Path  string
    IsDir bool
}

func main() {
    var files []fileMeta
    err := filepath.Walk(MAIN_FOLDER_NAME, func(path string, info os.FileInfo, err error) error {
        files = append(files, fileMeta{Path: path, IsDir: info.IsDir()})
        return nil
    })
    if err != nil {
        log.Fatalln(err)
    }

    z, err := os.Create(ZIP_FILE_NAME)
    if err != nil {
        log.Fatalln(err)
    }
    defer z.Close()

    zw := zip.NewWriter(z)
    defer zw.Close()

    for _, f := range files {
        path := f.Path
        if f.IsDir {
            path = fmt.Sprintf("%s%c", path, os.PathSeparator)
        }

        w, err := zw.Create(path)
        if err != nil {
            log.Fatalln(err)
        }

        if !f.IsDir {
            file, err := os.Open(f.Path)
            if err != nil {
                log.Fatalln(err)
            }
            defer file.Close()

            if _, err = io.Copy(w, file); err != nil {
                log.Fatalln(err)
            }
        }
    }
}