背景:
測試的接口是上傳一個zip文件,zip文件里是多個文件。
普通的壓縮文件的方式,要么zip里還有一層目錄,要么不能壓縮多個文件到一個zip,經過調研,找到了如下這種方式,可以同時將多個文件壓縮成一個zip包。
上代碼:
package main import ( "archive/zip" "fmt" "io" "os" "strconv" "time" ) func main() { //要壓縮成一個zip的多個文件的路徑 files := []string{"square_preview.png", "theme_publish.json", "keyboard_bg.png"} now := strconv.FormatInt(time.Now().UnixNano(), 10) //設置輸出的zip的路徑 output := "D:/zip/" + now + ".zip" if err := ZipFiles(output, files); err != nil { panic(err) } } func ZipFiles(filename string, files []string) error { fmt.Println("start zip file......") //創建輸出文件目錄 newZipFile, err := os.Create(filename) if err != nil { return err } defer newZipFile.Close() //創建空的zip檔案,可以理解為打開zip文件,准備寫入 zipWriter := zip.NewWriter(newZipFile) defer zipWriter.Close() // Add files to zip for _, file := range files { if err = AddFileToZip(zipWriter, file); err != nil { return err } } return nil } func AddFileToZip(zipWriter *zip.Writer, filename string) error { //打開要壓縮的文件 fileToZip, err := os.Open(filename) if err != nil { return err } defer fileToZip.Close() //獲取文件的描述 info, err := fileToZip.Stat() if err != nil { return err } //FileInfoHeader返回一個根據fi填寫了部分字段的Header,可以理解成是將fileinfo轉換成zip格式的文件信息 header, err := zip.FileInfoHeader(info) if err != nil { return err } header.Name = filename /* 預定義壓縮算法。 archive/zip包中預定義的有兩種壓縮方式。一個是僅把文件寫入到zip中。不做壓縮。一種是壓縮文件然后寫入到zip中。默認的Store模式。就是只保存不壓縮的模式。 Store unit16 = 0 //僅存儲文件 Deflate unit16 = 8 //壓縮文件 */ header.Method = zip.Deflate //創建壓縮包頭部信息 writer, err := zipWriter.CreateHeader(header) if err != nil { return err } //將源復制到目標,將fileToZip 寫入writer 是按默認的緩沖區32k循環操作的,不會將內容一次性全寫入內存中,這樣就能解決大文件的問題 _, err = io.Copy(writer, fileToZip) return err }