使用Golang生成壓縮文件的詳細(xì)教程
這是一個(gè)簡單的golang壓縮文件小案例,可做很多的拓展,這里使用的庫是archive/zip,在gopkg里面搜zip就行。
方法一
使用gin框架,獲取前端傳過來的文件壓縮成zip,存儲路徑入數(shù)據(jù)庫中,代碼簡單示例如下:
@Param file formData file true "上傳文件"
func UploadToZip(c *gin.Context){
//獲取前端傳過來的文件,如果有多個(gè)文件: 使用form,_ := c.MultipartForm()
//files := form.File["file"]
//然后遍歷files拿到每個(gè)文件
file,err := c.FormFile("file")
if err != nil {
response.Fail("參數(shù)有誤",c)
return
}
//創(chuàng)建目錄和指定文件名
err = c.SaveUploadedFile( file ,"files/" + file + file.Filename)
if err != nil {
response.Fail("存儲文件失敗",c)
return
}
//在指定的目錄生成你要的zip文件
create, err := os.Create("flies/dome.zip")
defer create.Close()
if err != nil {
response.Fail("創(chuàng)建失敗",c)
retuen
}
//創(chuàng)建一個(gè)zip流
writer := zip.NewWriter(create)
defer writer.Close()
//讀取存儲的目錄,將里面的文件壓縮
readFile ,err := os.ReadDir("files")
if err != nil {
response.Fail("讀取文件失敗",c)
retuen
}
//遍歷目錄,獲取單個(gè)文件
for _,rf := range readFile {
//只壓縮文件,目錄不做壓縮
if !rf.IsDir() {
//打開要壓縮的文件
open,err := os.Open("flies" + rf.Name())
if err != nil {
response.Fail("打開文件失敗",c)
retuen
}
//創(chuàng)建一個(gè)壓縮包里面的文件和文件名,這樣解壓后會(huì)有一個(gè)files目錄,目錄里面有壓縮的文件
f, _ := writer.Create("flies" + rf.Name())
//將文件壓縮成zip
if _,err := io.Copy(f,open);err != nil {
response.Fail("壓縮失敗",c)
retuen
}
}
}
//將壓縮路徑存放數(shù)據(jù)庫
...
response.OK("壓縮成功",c)
}
方法二
壓縮實(shí)現(xiàn)過程
創(chuàng)建壓縮歸檔文件
首先需要?jiǎng)?chuàng)建歸檔文件,與其他普通文件一樣。使用os包的os.Create函數(shù):
func Create(name string) (*File, error)
該方法創(chuàng)建或刪除給定名稱文件。如果文件已存在則刪除重新創(chuàng)建,如果不存在,創(chuàng)建文件,模式為0666。創(chuàng)建成功返回File用于讀寫,關(guān)聯(lián)文件描述符為O_RDWR,反之報(bào)錯(cuò),類型為*PathError。
初始化歸檔文件zip.Writer
使用 archive/zip 包 中的zip.NewWriter 函數(shù),用于寫數(shù)據(jù)(文件或目錄)至最終的壓縮文件。
語法如下:
func NewWriter(w io.Writer) *Writer
NewWriter 返回Writer寫
使用zip.Writer.Create增加文件壓縮文件
上面已創(chuàng)建了zip.Writer,可以增加文件和目錄至壓縮文件,使用zip.Writer.Create函數(shù):
func (w *Writer) Create(name string) (io.Writer, error)
方法通過文件名稱增加文件至壓縮文件,返回Writer用于寫文件內(nèi)容,文件內(nèi)容將被壓縮。文件名稱必須為相對路徑,不能以驅(qū)動(dòng)器字母(C:)或斜杠開頭,僅允許正斜杠。如果增加目錄,需要在名稱后面增加尾斜杠。在下一次調(diào)用Create, CreateHeader, 或 Close方法之前,文件內(nèi)容必須被寫入io.Writer.
使用 io.Copy 或 io.Writer.Write 寫文件內(nèi)容
zip.Writer.Create返回io.Writer,用于寫數(shù)據(jù),所以任何文件內(nèi)容可以流入或?qū)懭朐揥riter,也可以使用io.Copy函數(shù)。
func Copy(dst Writer, src Reader) (written int64, err error)
Copy函數(shù)從src至dst,直達(dá)EOF或遇到錯(cuò)誤。返回拷貝的字節(jié)數(shù)以及錯(cuò)誤(如果有錯(cuò)誤發(fā)生)。
使用zip.Writer.Close關(guān)閉壓縮文件
所有文件和目錄寫入至壓縮文件后,需要通過zip.Writer.Close方法關(guān)閉寫生成壓縮文件,即寫所有數(shù)據(jù)至底層數(shù)據(jù)流。
func (w *Writer) Close() error
實(shí)例代碼
下面示例壓縮兩個(gè)文件(txt和csv文件)生成單個(gè)壓縮文件。這兩個(gè)文件分別在壓縮文件的不同子目錄中。
package main
import (
"archive/zip"
"fmt"
"io"
"os"
)
func main() {
fmt.Println("creating zip archive...")
archive, err := os.Create("archive.zip")
if err != nil {
panic(err)
}
defer archive.Close()
zipWriter := zip.NewWriter(archive)
fmt.Println("opening first file...")
f1, err := os.Open("test.csv")
if err != nil {
panic(err)
}
defer f1.Close()
fmt.Println("writing first file to archive...")
w1, err := zipWriter.Create("csv/test.csv")
if err != nil {
panic(err)
}
if _, err := io.Copy(w1, f1); err != nil {
panic(err)
}
fmt.Println("opening second file")
f2, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer f2.Close()
fmt.Println("writing second file to archive...")
w2, err := zipWriter.Create("txt/test.txt")
if err != nil {
panic(err)
}
if _, err := io.Copy(w2, f2); err != nil {
panic(err)
}
fmt.Println("closing zip archive...")
zipWriter.Close()
}
運(yùn)行程序,生成日志:
creating zip archive... opening first file... writing first file to archive... opening second file writing second file to archive... closing zip archive...
最后解壓壓縮文件,和我們期望的一致:
$ unzip -l archive.zip
Archive: archive.zip
Length Date Time Name
--------- ---------- ----- ----
50 1980-00-00 00:00 csv/test.csv
16 1980-00-00 00:00 txt/test.txt
--------- -------
66 2 files
總結(jié)
以上就是使用Golang生成壓縮文件的詳細(xì)教程的詳細(xì)內(nèi)容,更多關(guān)于Golang生成壓縮文件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
go 代碼的調(diào)試---打印調(diào)用堆棧的實(shí)例
下面小編就為大家?guī)硪黄猤o 代碼的調(diào)試---打印調(diào)用堆棧的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
go語言數(shù)組及結(jié)構(gòu)體繼承和初始化示例解析
這篇文章主要為大家介紹了go語言數(shù)組及結(jié)構(gòu)體繼承和初始化示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
Golang兩行代碼實(shí)現(xiàn)發(fā)送釘釘機(jī)器人消息
創(chuàng)建一個(gè)釘釘機(jī)器人必須使用加簽,本文通過Golang兩行代碼實(shí)現(xiàn)發(fā)送釘釘機(jī)器人消息,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2021-12-12
Go語言設(shè)計(jì)模式之結(jié)構(gòu)型模式
本文主要聚焦在結(jié)構(gòu)型模式(Structural Pattern)上,其主要思想是將多個(gè)對象組裝成較大的結(jié)構(gòu),并同時(shí)保持結(jié)構(gòu)的靈活和高效,從程序的結(jié)構(gòu)上解決模塊之間的耦合問題2021-06-06
golang的database.sql包和事務(wù)處理操作步驟
事務(wù)是數(shù)據(jù)庫操作中的一個(gè)邏輯單元,由一系列的數(shù)據(jù)庫操作組成,這一系列操作要么全部執(zhí)行并且提交,要么全部回滾,確保數(shù)據(jù)的一致性和完整性,這篇文章主要介紹了golang的database.sql包和事務(wù)處理操作步驟,需要的朋友可以參考下2025-04-04
Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換
在軟件開發(fā)的世界里,數(shù)據(jù)類型轉(zhuǎn)換是一項(xiàng)基礎(chǔ)而重要的技能,尤其在Go語言這樣類型嚴(yán)格的語言中,正確高效地進(jìn)行類型轉(zhuǎn)換對于性能優(yōu)化和代碼質(zhì)量至關(guān)重要,本文給大家介紹了Go實(shí)現(xiàn)字符串與數(shù)字的高效轉(zhuǎn)換,需要的朋友可以參考下2024-02-02

