tar是用於文件歸檔,gzip用於壓縮。僅僅用tar的話,達不到壓縮的目的。我們常見的tar.gz就是用gzip壓縮生成的tar歸檔文件。
go實現tar壓縮與解壓與zip類似,區別在於tar需要使用gzip進行處理。tar與zip的Header不同。代碼如下
package tartest import ( "archive/tar" "compress/gzip" "io" "os" "strings" ) //壓縮 使用gzip壓縮成tar.gz func Compress(files []*os.File, dest string) error { d, _ := os.Create(dest) defer d.Close() gw := gzip.NewWriter(d) defer gw.Close() tw := tar.NewWriter(gw) defer tw.Close() for _, file := range files { err := compress(file, "", tw) if err != nil { return err } } return nil } func compress(file *os.File, prefix string, tw *tar.Writer) error { info, err := file.Stat() if err != nil { return err } if info.IsDir() { prefix = prefix + "/" + info.Name() fileInfos, err := file.Readdir(-1) if err != nil { return err } for _, fi := range fileInfos { f, err := os.Open(file.Name() + "/" + fi.Name()) if err != nil { return err } err = compress(f, prefix, tw) if err != nil { return err } } } else { header, err := tar.FileInfoHeader(info, "") header.Name = prefix + "/" + header.Name if err != nil { return err } err = tw.WriteHeader(header) if err != nil { return err } _, err = io.Copy(tw, file) file.Close() if err != nil { return err } } return nil } //解壓 tar.gz func DeCompress(tarFile, dest string) error { srcFile, err := os.Open(tarFile) if err != nil { return err } defer srcFile.Close() gr, err := gzip.NewReader(srcFile) if err != nil { return err } defer gr.Close() tr := tar.NewReader(gr) for { hdr, err := tr.Next() if err != nil { if err == io.EOF { break } else { return err } } filename := dest + hdr.Name file, err := createFile(filename) if err != nil { return err } io.Copy(file, tr) } return nil } func createFile(name string) (*os.File, error) { err := os.MkdirAll(string([]rune(name)[0:strings.LastIndex(name, "/")]), 0755) if err != nil { return nil, err } return os.Create(name) }