Search code examples
gozip

Recursively zipping a directory in golang


I essentially want to implement these commands in Golang:

cd somedir ; zip -r ../zipped.zip . * ; cd ..

I'm trying to zip folders and files within a parent directory without including the parent directory. This post is similar:

https://askubuntu.com/questions/521011/zip-an-archive-without-including-parent-directory


Solution

  • "how do I recursively zip in Golang"

    Something like this...

    package rzip
    
    import (
        "archive/zip"
        "io"
        "os"
        "path/filepath"
        "strings"
    )
    
    func RecursiveZip(pathToZip, destinationPath string) error {
        destinationFile, err := os.Create(destinationPath)
        if err != nil {
            return err
        }
        myZip := zip.NewWriter(destinationFile)
        err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, err error) error {
            if info.IsDir() {
                return nil
            }
            if err != nil {
                return err
            }
            relPath := strings.TrimPrefix(filePath, filepath.Dir(pathToZip))
            zipFile, err := myZip.Create(relPath)
            if err != nil {
                return err
            }
            fsFile, err := os.Open(filePath)
            if err != nil {
                return err
            }
            _, err = io.Copy(zipFile, fsFile)
            if err != nil {
                return err
            }
            return nil
        })
        if err != nil {
            return err
        }
        err = myZip.Close()
        if err != nil {
            return err
        }
        return nil
    }
    

    As for problems with docx files and your implementation, it's difficult to see what the problem might be without being able to see your code.

    EDIT:

    To create a zip with all files in the same dir you just need to change the path of the files you create inside your archive.

        relPath := strings.TrimPrefix(filePath, filepath.Dir(pathToZip))
        zipFile, err := myZip.Create(relPath)
    

    Becomes

         flatPath := filepath.Base(pathToZip)
         zipFile, err := myZip.Create(flatPath)
    

    To maintain directory structure, but omit the root directory

         relPath := strings.TrimPrefix(filePath, pathToZip)
         zipFile, err := myZip.Create(relPath)
    

    Cheers,

    Mark