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

问题描述 投票:0回答:2

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

这是文件夹结构。

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)

    }

}
go zip
2个回答
0
投票

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

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)
            }
        }
    }
}

0
投票

我尝试过,但对我不起作用 这是一个简单的例子

package main

import (
    "archive/zip"
    "fmt"
    "net/http"
)

func addEmptyDirectoryToZip(zipWriter *zip.Writer, directoryName string) error {
    header := &zip.FileHeader{
        Name:   directoryName + "/",
        Method: zip.Store,
    }

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

    _, err = writer.Write([]byte{})
    return err
}

func createZipAndWriteToResponse(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/zip")

    w.Header().Set("Content-Disposition", "attachment; filename=example.zip")

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


    err := addEmptyDirectoryToZip(zipWriter, "empty_folder")
    if err != nil {
        fmt.Println(err)
        http.Error(w, "Failed to add directory to zip", http.StatusInternalServerError)
        return
    }

    fmt.Println("Archive created")
}

func main() {
    http.HandleFunc("/download", createZipAndWriteToResponse)

    http.ListenAndServe(":8080", nil)
}

存档为空 请帮助我!

© www.soinside.com 2019 - 2024. All rights reserved.