-
-
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
nil
instead oferr
in this case?