本來計劃至少一周總結(jié)一次學到的東西,不過好像沒有實現(xiàn)啊??
一看時間都4月1號了,一個月了,總該寫點啥
最近運氣不好,出了很多事情,雖然都是不足為外人道的東西,但確實影響心情,希望大家每天都能開開心心的
今天寫一下前幾天遇到的一個需求:通過一個URL獲取用戶信息的zip文件
不涉及過多業(yè)務內(nèi)容的話,就是要寫一個小Demo,通過一個給定URL,獲取一個zip文件
實現(xiàn)一個極簡單的URL處理路由
既然是寫Demo,那么肯定路由就Golang最簡單的ListenAndServe就好了
func main() {
http.HandleFunc("/zipdownload", zipHandler)
log.Println("Listening...")
http.ListenAndServe(":9999", nil)
}
完成zipHandler函數(shù)
按照Golang的Handler函數(shù)簽名邀請,完成zipHandler函數(shù)
func zipHandler(rw http.ResponseWriter, r *http.Request) {
zipName := "ZipTest.zip"
rw.Header().Set("Content-Type", "application/zip")
rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipName))
err := getZip(rw)
if err != nil {
log.Fatal(err)
}
}
設(shè)置響應頭信息
rw.Header().Set("Content-Type", "application/zip")
設(shè)置response的頭信息中的文件類型,對于zip文件,一般可以設(shè)置為application/zip或application/octet-stream
更具體的說明,可以在Complete list of MIME types獲得,我是選擇了application/zip來告訴服務器精確的文件類型
rw.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", zipName))
設(shè)置Content-Disposition為attachment即附件類型,同時設(shè)置附件文件名為我們給定的zipName
響應頭信息中的Content-Disposition用于告知瀏覽器其獲取到的文件是需要展示與頁面內(nèi)還是需要作為附件保存到用戶本地,如果需要展示在頁面內(nèi),設(shè)置為inline,否則設(shè)置為attachemnt,在設(shè)置為attachment時還可以額外規(guī)定該附件的文件名,更具體的說明,可以在Content-Disposition獲得
完成這兩句代碼后,功能其實已經(jīng)完成了一大半了,最初我就是被這個地方卡住了,在獲得需求時思想泡里充滿了怎么樣才能讓HTTP響應得到一個zip文件并且讓瀏覽器將這個文件下載下來而不是試圖展示出來的問題
完成getZip函數(shù)
這里我們只需要完成一個比較基礎(chǔ)的zip流程就好,就像我上面說的,這個需求,最難的其實是上面對HTTP Response中Header信息的了解
func getZip(w io.Writer) error {
zipW := zip.NewWriter(w)
defer zipW.Close()
for i := 0; i < 5; i++ {
f, err := zipW.Create(strconv.Itoa(i) + ".txt")
if err != nil {
return err
}
_, err = f.Write([]byte(fmt.Sprintf("Hello file %d", i)))
if err != nil {
return err
}
}
return nil
}
創(chuàng)建zip.Writer
zipW := zip.NewWriter(w)
該方法創(chuàng)建一個zip.Writer,用于向zip文件中寫入內(nèi)容,即打包的文件
參數(shù)為io.Writer,那么我們這里當然就是使用http.ResponseWriter
返回值為一個zip.Writer,最后的zip內(nèi)容都會寫入這個zip.Writer,而最終當然是寫入了參數(shù)的io.Writer中,也就是我們的http.ResponseWriter中
記得defer zipW.Close()關(guān)閉zip.Writer
向zip.Writer中寫入文件
f, err := zipW.Create(strconv.Itoa(i) + ".txt")
該方法向zip.Writer中添加一個文件,也就是說向zip文件中添加一個文件
參數(shù)字為字符串,會作為寫入zip中的文件的文件名
第一個返回值為一個io.Writer,用于向其中,也就是向我們添加到zip的文件中,寫入文件內(nèi)容,即如_, err = f.Write([]byte(fmt.Sprintf("Hello file %d", i)))代碼所示,我們向文件中寫入了簡單的字符串
運行程序
接下來,只需要在程序main.go所在目錄運行go run main.go就可以在你的瀏覽器訪問localhost:9999/zipdownload了,瀏覽器會下載一個zip文件

最后,代碼已經(jīng)上傳到了我的Github倉庫可以直接下載測試
最最后,上一篇文章的時候我吐槽了下簡書總是不讓我貼了外鏈圖片等文章發(fā)布,今天又試了下,居然沒這個問題了,比如這個文章里的圖片就是外鏈的,開心
最最最后,當然還是歡迎訪問我的個人博客