一天一个Golang包,慢慢学习之“archive/zip”
昨天阅读了archive包的tar包,对Go语言操作压缩包有了一定的基础,今天就继续把另外一个包“zip”也来熟悉一下。
阅读文档: 官方pkg地址:https://golang.org/pkg/archive/zip/
今天同样从官方的包文档中提取几个主要的内容出来分享一下:
常量
1 2 3 4 const ( Store uint16 = 0 Deflate uint16 = 8 )
变量
1 2 3 4 5 var ( ErrFormat = errors.New("zip: not a valid zip file" ) ErrAlgorithm = errors.New("zip: unsupported compression algorithm" ) ErrChecksum = errors.New("zip: checksum error" ) )
FileHeader结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 type FileHeader struct { Name string Comment string NonUTF8 bool CreatorVersion uint16 ReaderVersion uint16 Flags uint16 Method uint16 Modified time.Time ModifiedTime uint16 ModifiedDate uint16 CRC32 uint32 CompressedSize uint32 UncompressedSize uint32 CompressedSize64 uint64 UncompressedSize64 uint64 Extra []byte ExternalAttrs uint32 }
FileHeader相关的方法:
func FileInfoHeader(fi os.FileInfo) (*FileHeader, error) // 通过传入的fi填充一个FileHeader并返回,由于os.FileInfo的Name方法只返回文件描述的Name,所以实际使用有可能需要自行修改为完整的全路径
func (h *FileHeader) FileInfo() os.FileInfo // 返回一个os.FileInfo
func (h *FileHeader) ModTime() time.Time // 修改时间
func (h *FileHeader) Mode() (mode os.FileMode) // 权限和模式位
func (h *FileHeader) SetModTime(t time.Time) // 设置修改时间
func (h *FileHeader) SetMode(mode os.FileMode) // 设置权限
ReadCloser结构体
1 2 3 4 type ReadCloser struct { Reader }
ReadCloser的相关方法:
func OpenReader(name string) (*ReadCloser, error) // 传入文件名(路径),返回一个ReadCloser指针(继承了Reader)
func (rc *ReadCloser) Close() error // 关闭ReadCloser
Reader结构体
1 2 3 4 5 type Reader struct { File []*File Comment string }
Reader的相关方法:
func NewReader(r io.ReaderAt, size int64) (*Reader, error) // 从r中读取size个字节并返回一个新的Reader
func (z *Reader) RegisterDecompressor(method uint16, dcomp Decompressor)
Writer结构体
1 2 3 type Writer struct { }
Writer的相关方法:
func NewWriter(w io.Writer) *Writer // 创建并返回一个将zip文件写入w的Writer
func (w *Writer) Close() error // 关闭Writer
func (w *Writer) Create(name string) (io.Writer, error) // 使用name添加一个文件到zip文件中,返回一个Writer。name必须是相对路径,不能以设备或斜杠开头,用’/‘作为分隔符。新增文件内容必须在下一次调用CreateHeader、Create或Close方法前全部写入。
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) // 使用fh所描述的元数据添加一个文件到zip文件中,并返回一个用于写入数据的io.Writer。
func (w *Writer) Flush() error // 将缓存写入底层IO
等等..
实现一个跟昨天一样的需求:简单的创建和读取压缩包,传送门
代码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 package zipimport ( "archive/zip" "fmt" "io" "log" "os" "time" ) var ( filePath = "/tmp/go/learn/data/zipArchive.zip" ) func CreateArchive () { fmt.Println("This is function CreateArchive called" ) var files = []struct { Name, Body string }{ {"Readme.md" , "## Hello World\n1. line 1\n2. line 2\n3. line 3" }, {"gopher.txt" , "Gopher names:\nGorge\nGeoffrey\nGonzo" }, {"todo.txt" , "Get animal handling licence.\nWrite more examples" }, {"myDir/file.txt" , "This is a sub dir's file" }, } fi, err := os.Create(filePath) defer fi.Close() if err != nil { log.Fatal(err) } zw := zip.NewWriter(fi) for _, file := range files { fh := &zip.FileHeader{ Name: file.Name, Modified: time.Now(), } if f, err := zw.CreateHeader(fh); err != nil { log.Fatal(err) }else { if _, err := f.Write([]byte (file.Body));err != nil { log.Fatal(err) } } } if err = zw.Close(); err != nil { log.Fatal(err) } fmt.Println("Created Archive file is stored in:" , filePath) } func ReadArchive () { fmt.Println("This is function ReadeArchive called" ) zr, err := zip.OpenReader(filePath) if err != nil { log.Fatal(err) } defer zr.Close() for _, f := range zr.File { fmt.Printf("\tContents of %s:\n" ,f.Name) if rc, err := f.Open();err != nil { log.Fatal(err) }else { if _, err := io.Copy(os.Stdout, rc, ); err != nil { log.Fatal(err) } rc.Close() fmt.Println() } } }
通过今天的学习,突然发现了昨天的tar并没有涉及到压缩,所以它应该就是个普通的归档,而zip中带有了压缩算法,所以它可以被称为压缩包。不过我今天也悄悄的看了一下tar.gz的相关内容,非常简单!这里就不多说,感兴趣的自行移步官方文档。