package main
import ( "archive/zip" "errors" "fmt" "io" "os" "path/filepath" "strings" )
func SubString(str string, begin, length int) (substr string) { // 将字符串的转换成[]rune rs := []rune(str) lth := len(rs)
// 简单的越界判断
if begin < 0 {
begin = 0
}
if begin >= lth {
begin = lth
}
end := begin + length
if end > lth {
end = lth
}
// 返回子串
return string(rs[begin:end])
}
const ( singleFileByteLimit = 107374182400 // 1 GB chunkSize = 4096 // 4 KB )
func copyContents(r io.Reader, w io.Writer) error { var size int64 b := make([]byte, chunkSize) for { // we limit the size to avoid zip bombs size += chunkSize if size > singleFileByteLimit { return errors.New("file too large, please contact us for assistance") } // read chunk into memory length, err := r.Read(b[:cap(b)]) if err != nil { if err != io.EOF { return err } if length == 0 { break } } // write chunk to zip file _, err = w.Write(b[:length]) if err != nil { return err } } return nil }
// We need a struct internally because the filepath WalkFunc // doesn't allow custom params. So we save them here so it can // access them type zipper struct { srcFolder string destFile string writer *zip.Writer }
// internal function to zip a file, called by filepath.Walk on each file func (z *zipper) zipFile(path string, f os.FileInfo, err error) error { if err != nil { return err } // only zip files (directories are created by the files inside of them) // TODO allow creating folder when no files are inside if !f.Mode().IsRegular() || f.Size() == 0 { return nil } // open file file, err := os.Open(path) if err != nil { return err } defer file.Close() // create new file in zip fileName := strings.TrimPrefix(path, z.srcFolder+"/")
result := SubString(fileName, len(z.srcFolder)-1, len(fileName)-len(z.srcFolder)+1)
fmt.Println("fileName:", result)
fmt.Println(path)
w, err := z.writer.Create(result)
if err != nil {
return err
}
// copy contents of the file to the zip writer
err = copyContents(file, w)
if err != nil {
return err
}
return nil
}
// internal function to zip a folder func (z *zipper) zipFolder() error { // create zip file zipFile, err := os.Create(z.destFile) if err != nil { return err } defer zipFile.Close() // create zip writer z.writer = zip.NewWriter(zipFile) err = filepath.Walk(z.srcFolder, z.zipFile) if err != nil { return nil } // close the zip file err = z.writer.Close() if err != nil { return err } return nil }
// ZipFolder zips the given folder to the a zip file // with the given name func ZipFolder(srcFolder string, destFile string) error { z := &zipper{ srcFolder: srcFolder, destFile: destFile, } return z.zipFolder() } func main() { // file write ZipFolder("d://test//src", "d://test//src2.apk") fmt.Println("zip ok") }
有疑问加站长微信联系(非本文作者)
