七叶笔记 » golang编程 » Golang tar包解压和压缩,内存操作

Golang tar包解压和压缩,内存操作

tar.gz包压缩

 type TarFileContent struct {

Name    string

Content []byte

}

// 直接写到文件

func writeToFile(tarFileList []TarFileContent, file *os.File) error {

// 如果不是gzip格式, 可以直接用 tar.NewWriter(file)

gz := gzip.NewWriter(file)

tw := tar.NewWriter(gz)

defer func() {

tw.Close()

gz.Close()

}()

for _, f := range tarFileList {

hdr := &tar.Header{

Name:     f.Name,

Mode:     0644,

Size:     int64(len(f.Content)),

ModTime:  time.Now(),

Typeflag: tar.TypeReg,

}

err := tw.WriteHeader(hdr)

if err != nil {

return err

}

_, err = tw.Write(f.Content)

if err != nil {

return err

}

}

return nil

}

// 写到内存

func writeToBuf(tarFileList []TarFileContent, buf *bytes.Buffer) error {

gz := gzip.NewWriter(buf)

tw := tar.NewWriter(gz)

defer func() {

tw.Close()

gz.Close()

}()

for _, f := range tarFileList {

hdr := &tar.Header{

Name:     f.Name,

Mode:     0644,

Size:     int64(len(f.Content)),

ModTime:  time.Now(),

Typeflag: tar.TypeReg,

}

err := tw.WriteHeader(hdr)

if err != nil {

return err

}

_, err = tw.Write(f.Content)

if err != nil {

return err

}

}

return nil

}  
 // 测试写到内存

testContentList := []TarFileContent{

{

"meta.json",

`{"a":"aaa"}`,

},

{

"x1/x1.json",

`{"x1:"xxxx"}`,

},

{

"x2/x2.json",

`{"x2:"xxxx"}`,

},

}

buf := new(bytes.Buffer)

writeToBuf(testContentList, &buf)  

tar.gz包解压

 func parseTarData(tarData []byte) ([]TarFileContent, error) {

bf := bytes.NewBuffer(tarData)

// 如果不是gzip格式,可以直接用tar.NewReader(bf)

gr, err := gzip.NewReader(bf)

if err != nil {

return nil, err

}

defer gr.Close()

tr := tar.NewReader(gr)

  tarContentList := make([]TarFileContent, 0)

for {

hdr, err := tr.Next()

if err == io.EOF {

break // End of archive

}

if err != nil {

return nil, err

}

if hdr.Typeflag == tar.TypeDir {

continue

}

fileData, err := ioutil.ReadAll(tr)

if err != nil {

return nil, err

}

tarContentList = append(tarContentList, TarFileContent{Name: hdr.Name, **Content:** fileData})

}

}

return tarContentList, nil

}  

在压缩tar包时,写完所有二进制之后,需要先把 tw.Close() , 再把 gw.Close() , 这两个顺序一定不能颠倒,不然格式会出错,少写入512个byte。

相关文章