-
-
Save iamralch/424e6784facc0ba907ae to your computer and use it in GitHub Desktop.
| import ( | |
| "archive/zip" | |
| "io" | |
| "os" | |
| "path/filepath" | |
| "strings" | |
| ) | |
| func zipit(source, target string) error { | |
| zipfile, err := os.Create(target) | |
| if err != nil { | |
| return err | |
| } | |
| defer zipfile.Close() | |
| archive := zip.NewWriter(zipfile) | |
| defer archive.Close() | |
| info, err := os.Stat(source) | |
| if err != nil { | |
| return nil | |
| } | |
| var baseDir string | |
| if info.IsDir() { | |
| baseDir = filepath.Base(source) | |
| } | |
| filepath.Walk(source, func(path string, info os.FileInfo, err error) error { | |
| if err != nil { | |
| return err | |
| } | |
| header, err := zip.FileInfoHeader(info) | |
| if err != nil { | |
| return err | |
| } | |
| if baseDir != "" { | |
| header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) | |
| } | |
| if info.IsDir() { | |
| header.Name += "/" | |
| } else { | |
| header.Method = zip.Deflate | |
| } | |
| writer, err := archive.CreateHeader(header) | |
| if err != nil { | |
| return err | |
| } | |
| if info.IsDir() { | |
| return nil | |
| } | |
| file, err := os.Open(path) | |
| if err != nil { | |
| return err | |
| } | |
| defer file.Close() | |
| _, err = io.Copy(writer, file) | |
| return err | |
| }) | |
| return err | |
| } |
| import ( | |
| "archive/zip" | |
| "io" | |
| "os" | |
| "path/filepath" | |
| "strings" | |
| ) | |
| func unzip(archive, target string) error { | |
| reader, err := zip.OpenReader(archive) | |
| if err != nil { | |
| return err | |
| } | |
| if err := os.MkdirAll(target, 0755); err != nil { | |
| return err | |
| } | |
| for _, file := range reader.File { | |
| path := filepath.Join(target, file.Name) | |
| if file.FileInfo().IsDir() { | |
| os.MkdirAll(path, file.Mode()) | |
| continue | |
| } | |
| fileReader, err := file.Open() | |
| if err != nil { | |
| return err | |
| } | |
| defer fileReader.Close() | |
| targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) | |
| if err != nil { | |
| return err | |
| } | |
| defer targetFile.Close() | |
| if _, err := io.Copy(targetFile, fileReader); err != nil { | |
| return err | |
| } | |
| } | |
| return nil | |
| } |
The extract function will generate too many open file issue as the defer is only called once the function return, here an altered version:
func Unzip(archive, target string) error {
reader, err := zip.OpenReader(archive)
if err != nil {
return err
}
if err := os.MkdirAll(target, 0755); err != nil {
return err
}
for _, file := range reader.File {
path := filepath.Join(target, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(path, file.Mode())
continue
}
fileReader, err := file.Open()
if err != nil {
if fileReader != nil {
fileReader.Close()
}
return err
}
targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
fileReader.Close()
if targetFile != nil {
targetFile.Close()
}
return err
}
if _, err := io.Copy(targetFile, fileReader); err != nil {
fileReader.Close()
targetFile.Close()
return err
}
fileReader.Close()
targetFile.Close()
}
return nil
}The zipit function throws an error if the .zip file does not already exist. How do i remedy this?
// Check file
if _, err := os.Stat(archive); os.IsNotExist(err) {
return err
}
License?
If have a large files in multiple directory, the filepath.Walk would take a long time to process. Any possible to use goroutine to improve performance?
hi all, if I have some sub directories, in the code previous, it just make directory of sub directories, how can i restore those files in sub directories?
if r.File[f].FileInfo().IsDir() {
if err := os.MkdirAll(dstpath, os.ModePerm); err != nil {
return nil, err
}
}
in this piece of code, how could i copy those files which are in this directory?
You have to walk through the directories until you reach a regular file.
@Svett, thanks for the very useful code. I have a question on line 21 in compress.go. Is there any reason to return
nilinstead oferrin this case?