package ziptil import ( "archive/zip" "io" "os" "path/filepath" "strings" ) //解压zip文件 //@param zipFile 需要解压的zip文件 //@param dest 需要解压到的目录 //@return err 返回错误 func Unzip(zipFile, dest string) (err error) { dest = strings.TrimSuffix(dest, "/") + "/" // 打开一个zip格式文件 r, err := zip.OpenReader(zipFile) if err != nil { return err } defer r.Close() // 迭代压缩文件中的文件,打印出文件中的内容 for _, f := range r.File { if !f.FileInfo().IsDir() { //非目录,且不包含__MACOSX if folder := dest + filepath.Dir(f.Name); !strings.Contains(folder, "__MACOSX") { os.MkdirAll(folder, 0777) if fcreate, err := os.Create(dest + strings.TrimPrefix(f.Name, "./")); err == nil { if rc, err := f.Open(); err == nil { io.Copy(fcreate, rc) rc.Close() //不要用defer来关闭,如果文件太多的话,会报too many open files 的错误 fcreate.Close() } else { fcreate.Close() return err } } else { return err } } } } return nil } //压缩文件 func Zip(source, target string) error { zipFile, err := os.Create(target) if err != nil { return err } defer zipFile.Close() archive := zip.NewWriter(zipFile) defer archive.Close() source = strings.Replace(source, "\\", "/", -1) filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if err != nil { return err } path = strings.Replace(path, "\\", "/", -1) if path == source { return nil } header, err := zip.FileInfoHeader(info) if err != nil { return err } header.Name = strings.TrimPrefix(strings.TrimPrefix(strings.Replace(path, "\\", "/", -1), 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 } ////压缩指定文件或文件夹 ////@param dest 压缩后的zip文件目标,如/usr/local/hello.zip ////@param filepath 需要压缩的文件或者文件夹 ////@return err 错误。如果返回错误,则会删除dest文件 //func Zip(dest string, filepath ...string) (err error) { // if len(filepath) == 0 { // return errors.New("lack of file") // } // //创建文件 // fzip, err := os.Create(dest) // if err != nil { // return err // } // defer fzip.Close() // // var filelist []filetil.FileList // for _, file := range filepath { // if info, err := os.Stat(file); err == nil { // if info.IsDir() { //目录,则扫描文件 // if f, _ := filetil.ScanFiles(file); len(f) > 0 { // filelist = append(filelist, f...) // } // } else { //文件 // filelist = append(filelist, filetil.FileList{ // IsDir: false, // Name: info.Name(), // Path: file, // }) // } // } else { // return err // } // } // w := zip.NewWriter(fzip) // defer w.Close() // for _, file := range filelist { // if !file.IsDir { // if fw, err := w.Create(strings.TrimLeft(file.Path, "./")); err != nil { // return err // } else { // if fileContent, err := ioutil.ReadFile(file.Path); err != nil { // return err // } else { // if _, err = fw.Write(fileContent); err != nil { // return err // } // } // } // } // } // return //} func Compress(dst string, src string) (err error) { d, _ := os.Create(dst) defer d.Close() w := zip.NewWriter(d) defer w.Close() src = strings.Replace(src, "\\", "/", -1) f, err := os.Open(src) if err != nil { return err } //prefix := src[strings.LastIndex(src,"/"):] err = compress(f, "", w) if err != nil { return err } return nil } func compress(file *os.File, prefix string, zw *zip.Writer) error { info, err := file.Stat() if err != nil { return err } if info.IsDir() { if prefix != "" { prefix = prefix + "/" + info.Name() } else { prefix = info.Name() } fileInfos, err := file.Readdir(-1) if err != nil { return err } for _, fi := range fileInfos { f, err := os.Open(file.Name() + "/" + fi.Name()) if err != nil { return err } err = compress(f, prefix, zw) if err != nil { return err } } } else { header, err := zip.FileInfoHeader(info) if prefix != "" { header.Name = prefix + "/" + header.Name } if err != nil { return err } writer, err := zw.CreateHeader(header) if err != nil { return err } _, err = io.Copy(writer, file) file.Close() if err != nil { return err } } return nil }