Go语言中使用compress/gzip库进行文件压缩与解压

发表时间: 2024-05-23 11:31

go标准库的gzip包中提供了两个操作, 分别是压缩和解压

常量和变量

const (    NoCompression = flate.NoCompression // 不压缩    BestSpeed = flate.BestSpeed // 最快速度    BestCompression = flate.BestCompression // 最佳压缩比    DefaultCompression = flate.DefaultCompression // 默认压缩比)var (    // 当读取gzip数据时发现无效的校验和时将返回该错误    ErrChecksum = errors.New("gzip: invalid checksum")    // 当读取gzip数据时发现无效的数据头时将返回该错误    ErrHeader = errors.New("gzip: invalid header"))//数据头结构type Header struct {    Comment string // 文件注释    Extra []byte // 附加数据    ModTime time.Time // 文件修改时间    Name string // 文件名    OS byte // 操作系统类型}

(1) 压缩

type Writer struct {}

功能说明:该结果主要用于将文件写入到gzip包中, 并记录每个文件的数据头。

另外要注意的是, NewWriter(0与NewWriterLevel()的主要区别在于前者使用默认的压缩级别, 而后者可以指定自定义的压缩级别。单独操作gzip会比较麻烦, 可以与tar一起使用, 会比较方便。

compress.go

package mainimport (    "compress/gzip"    "log"    "os")func main() {    fw, err := os.Create("test.gzip") // 创建gzip包文件,返回*io.Writer    if err != nil {        log.Fatalln(err)    }    defer fw.Close()    // 实例化心得gzip.Writer    gw := gzip.NewWriter(fw)    defer gw.Close()    // 获取要打包的文件信息    fr, err := os.Open("test.exe") //需要压缩(打包)的文件    if err != nil {        log.Fatalln(err)    }    defer fr.Close()    // 获取文件头信息    fi, err := fr.Stat()    if err != nil {    log.Fatalln(err)    }    // 创建gzip.Header    gw.Header.Name = fi.Name()    // 读取文件数据    buf := make([]byte, fi.Size())    _, err = fr.Read(buf)    if err != nil {        log.Fatalln(err)    }    // 写入数据到zip包    _, err = gw.Write(buf)    if err != nil {        log.Fatalln(err)		}}

(2)解压

type Reader struct {}

功能说明:该结构主要用于读取gzip包的数据

uncompress.go

package mainimport (    "compress/gzip"    "log"    "os")func main() {    // 打开gzip文件    fr, err := os.Open("test.gzip")    if err != nil {        log.Fatalln(err)    }    defer fr.Close()    // 创建gzip.Reader    gr, err := gzip.NewReader(fr)    if err != nil {        log.Fatalln(err)    }    defer gr.Close()    // 读取文件内容    buf := make([]byte, 1024*1024*10) // 如果单独使用,需自己决定要读多少内容,根据官方文档的说法,你读出的内容可能超出你的所需(当你压缩gzip文件中有多个文件时,强烈建议直接和tar组合使用)    n, err := gr.Read(buf)    // 将包中的文件数据写入    fw, err := os.Create(gr.Header.Name) // gr.Header.Name 获取压缩文件的名称    if err != nil {        log.Fatalln(err)    }    _, err = fw.Write(buf[:n])    if err != nil {        log.Fatalln(err)    }}