Go的archive/zip
包提供了文件的压缩和解压,本例涉及到的API如下(仅列出重要部分):
// zip.Writer用来写入压缩包
type Writer struct {
// ...
}
// Create方法用来在zip包里创建文件,返回的io.Writer用来写内容
func (w *Writer) Create(name string) (io.Writer, error)
// zip.Reader用来读取压缩包
type Reader struct {
File []*File // File数组保存了所有的文件信息
// ...
}
// zip.File 表示压缩包中的文件
type File struct {
// ...
}
// 打开zip中的文件以读取,返回的io.ReadCloser用来读取内容
func (f *File) Open() (io.ReadCloser, error)
代码如下:
package main
import (
"archive/zip"
"io"
"log"
"os"
"path/filepath"
)
func zipDir(dir, zipFile string) {
fz, err := os.Create(zipFile)
if err != nil {
log.Fatalf("Create zip file failed: %s\n", err.Error())
}
defer fz.Close()
w := zip.NewWriter(fz)
defer w.Close()
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
fDest, err := w.Create(path[len(dir)+1:])
if err != nil {
log.Printf("Create failed: %s\n", err.Error())
return nil
}
fSrc, err := os.Open(path)
if err != nil {
log.Printf("Open failed: %s\n", err.Error())
return nil
}
defer fSrc.Close()
_, err = io.Copy(fDest, fSrc)
if err != nil {
log.Printf("Copy failed: %s\n", err.Error())
return nil
}
}
return nil
})
}
func unzipDir(zipFile, dir string) {
r, err := zip.OpenReader(zipFile)
if err != nil {
log.Fatalf("Open zip file failed: %s\n", err.Error())
}
defer r.Close()
for _, f := range r.File {
func() {
path := dir + string(filepath.Separator) + f.Name
os.MkdirAll(filepath.Dir(path), 0755)
fDest, err := os.Create(path)
if err != nil {
log.Printf("Create failed: %s\n", err.Error())
return
}
defer fDest.Close()
fSrc, err := f.Open()
if err != nil {
log.Printf("Open failed: %s\n", err.Error())
return
}
defer fSrc.Close()
_, err = io.Copy(fDest, fSrc)
if err != nil {
log.Printf("Copy failed: %s\n", err.Error())
return
}
}()
}
}
func main() {
zipDir("F:\\dumps", "F:\\dumps.zip")
unzipDir("F:\\dumps.zip", "F:\\dumps_copy")
}