您的位置:首页 > 编程语言 > Go语言

Go语言学习之archive/zip、compress/zlib、compress/gzip包(the way to go)

2017-06-23 14:11 1836 查看
生命不止,继续go go go !!!

曾经的曾经,写过这篇博客,介绍过使用archive/zip:

Go实战–压缩zip和解压缩unzip的应用(The way to go)

zip zlib gzip

zlib是一种数据压缩程序库,它的设计目标是处理单纯的数据(而不管数据的来源是什么)。

gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格式),它的设计目标是处理单个的文件。gzip在压缩文件中的数据时使用的就是zlib。为了保存与文件属性有关的信息,gzip需要在压缩文件(.gz)中保存更多的头信息内容,而zlib不用考虑这一点。但gzip只适用于单个文件,所以我们在UNIX/Linux上经常看到的压缩包后缀都是.tar.gz或*.tgz,也就是先用tar把多个文件打包成单个文件,再用gzip压缩的结果。

zip是适用于压缩多个文件的格式(相应的工具有PkZip和WinZip等),因此,zip文件还要进一步包含文件目录结构的信息,比gzip的头信息更多。但需要注意,zip格式可采用多种压缩算法,我们常见的zip文件大多不是用zlib的算法压缩的,其压缩数据的格式与gzip大不一样。

archive/zip

Package zip provides support for reading and writing ZIP archives.

读取zip

func unzip_with_archive_zip(archive, target string) error {
reader, err := zip.OpenReader(archive)
if err != nil {
return err
}

if err := os.MkdirAll(target, 0755); err != nil {
return err
}

for _, file := range reader.File {
path := filepath.Join(target, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(path, file.Mode())
continue
}

fileReader, err := file.Open()
if err != nil {
return err
}
defer fileReader.Close()

targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
return err
}
defer targetFile.Close()

if _, err := io.Copy(targetFile, fileReader); err != nil {
return err
}
}

return nil
}

func zipit_with_archive_zip(source, target string) error {
zipfile, err := os.Create(target)
if err != nil {
return err
}
defer zipfile.Close()

archive := zip.NewWriter(zipfile)
defer archive.Close()

info, err := os.Stat(source)
if err != nil {
return nil
}

var baseDir string
if info.IsDir() {
baseDir = filepath.Base(source)
}

filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

if baseDir != "" {
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
}

if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate
}

writer, err := archive.CreateHeader(header)
if err != nil {
return err
}

if info.IsDir() {
return nil
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})

return err
}


compress/zlib

Package zlib implements reading and writing of zlib format compressed data, as specified in RFC 1950.

那么何为RFC 1950?

一种标准规范吧。

func NewReader

func NewReader(r io.Reader) (io.ReadCloser, error)


NewReader creates a new ReadCloser.

func NewWriter

func NewWriter(w io.Writer) *Writer


NewWriter creates a new Writer. Writes to the returned Writer are compressed and written to w.

func zipit_with_compress_zlib() {
var b bytes.Buffer

w := zlib.NewWriter(&b)
w.Write([]byte("hello, world\n"))
w.Close()
fmt.Println(b.Bytes())
// Output: [120 156 202 72 205 201 201 215 81 40 207 47 202 73 225 2 4 0 0 255 255 33 231 4 147]
}

func unzip_with_compress_zlib() {
buff := []byte{120, 156, 202, 72, 205, 201, 201, 215, 81, 40, 207,
47, 202, 73, 225, 2, 4, 0, 0, 255, 255, 33, 231, 4, 147}
b := bytes.NewReader(buff)

r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, r)
r.Close()
}


compress/gzip

Package gzip implements reading and writing of gzip format compressed files, as specified in RFC 1952.

这里可以很清楚的看到gzip与zlib两个包的区别:就是针对不同格式的压缩文件。

func NewReader

func NewReader(r io.Reader) (*Reader, error)


NewReader creates a new Reader reading the given reader. If r does not also implement io.ByteReader, the decompressor may read more data than necessary from r.

func NewWriter

func NewWriter(w io.Writer) *Writer


NewWriter returns a new Writer. Writes to the returned writer are compressed and written to w.

例子:

package main

import (
"compress/gzip"
"fmt"
"os"
)

func main() {

original := "Hello World!"
f, _ := os.Create("./file.gz")
w := gzip.NewWriter(f)
w.Write([]byte(original))
w.Close()
fmt.Println("COMPRESS DONE")

f, _ = os.Open("./file.gz")
reader, _ := gzip.NewReader(f)
result := make([]byte, 100)
count, _ := reader.Read(result)
fmt.Println(count)
fmt.Println(string(result))
}


func NewWriterLevel

func NewWriterLevel(w io.Writer, level int) (*Writer, error)


NewWriterLevel is like NewWriter but specifies the compression level instead of assuming DefaultCompression.

常量:

const (
NoCompression      = flate.NoCompression
BestSpeed          = flate.BestSpeed
BestCompression    = flate.BestCompression
DefaultCompression = flate.DefaultCompression
HuffmanOnly        = flate.HuffmanOnly
)


例子:

package main

import (
"compress/gzip"
"fmt"
"os"
)

func main() {
test := "There are moments in life when you miss someone so much that you just want to pick them from your dreams and hug them for real!"
test += "Dream what you want to dream;"
test += "go where you want to go;"
test += "be what you want to be,because you have only one life and one chance to do all the things you want to do."

// Write with BestSpeed.
fmt.Println("BESTSPEED")
f, _ := os.Create("./file-bestspeed.gz")
w, _ := gzip.NewWriterLevel(f, gzip.BestSpeed)
w.Write([]byte(test))
w.Close()

// Write with BestCompression.
fmt.Println("BESTCOMPRESSION")
f, _ = os.Create("./file-bestcompression.gz")
w, _ = gzip.NewWriterLevel(f, gzip.BestCompression)
w.Write([]byte(test))
w.Close()
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: