From b9885bed8160c543fc29f98260082b1fa8fde118 Mon Sep 17 00:00:00 2001 From: rmanach Date: Tue, 12 Apr 2022 14:09:20 +0200 Subject: [PATCH] create zip archive --- .gitignore | 4 ++- main.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f54ebbb..86432cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ # binary file -packer \ No newline at end of file +packer +# zip file +*.zip \ No newline at end of file diff --git a/main.go b/main.go index a3d2826..40838e3 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,10 @@ package main import ( + "archive/zip" "fmt" "github.com/akamensky/argparse" + "io" "log" "os" fp "path/filepath" @@ -48,7 +50,7 @@ func walkDirFiltered(directory string, regex re.Regexp) ([]string, error) { return err } if !info.IsDir() && regex.MatchString(path) { - fmt.Println(path) + log.Println("file found :", path) files = append(files, path) } return err @@ -62,6 +64,70 @@ func getFilesFromDirectoryPath(directory string, regex re.Regexp) ([]string, err return files, err } +// writeFileContent - write file content into zipped file +// chunking is used to avoid memory errors with large files +func writeFileContent(f *os.File, zf io.Writer) (err error) { + const chunkSize = 4 + b := make([]byte, chunkSize) + + for { + _, err := f.Read(b) + if err != nil { + if err != io.EOF { + continue + } + break + } + zf.Write(b) + } + + return err +} + +// generateZip - create a zip archive +// * outputPath: zip archive full path +// * filePaths: files path +func generateZip(outputPath string, filepaths []string) (err error) { + + // create a zipfile from `outputPath` + zipPath, err := os.Create(outputPath) + if err != nil { + return err + } + defer zipPath.Close() + + // create a new zip archive from `zipPath` + w := zip.NewWriter(zipPath) + + for _, filepath := range filepaths { + // open matching regex file + f, err := os.Open(filepath) + if err != nil { + log.Println("[ERROR] :", err) + continue + } + + // create a zipped file + zf, err := w.Create(filepath) + if err != nil { + log.Println("[ERROR] :", err) + f.Close() + continue + } + + // write file content into zipped file + err = writeFileContent(f, zf) + + // clean up opened file + f.Close() + } + + // make sure to check the error on Close. + err = w.Close() + + return err +} + func main() { // parse arguments @@ -83,6 +149,9 @@ func main() { log.Printf("looking for file '%s' in '%s' ...", rd.String(), directory) files, err := getFilesFromDirectoryPath(directory, rd) + // generating zip archive log.Printf("files found : %d", len(files)) - log.Printf("files zipped in %s", outputPath) + generateZip(outputPath, files) + + log.Printf("zip archive generated in %s", outputPath) }