golang访问tar文件

CodingCode · · 2044 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang访问tar文件

下面例子提取一个tar文件的内容:

package main

import (
    "io"
    "os"
    "fmt"
    "path"
    "encoding/json"
    "archive/tar"
)

func extract(tarfile string) {
    reader, err := os.Open(tarfile)
    if err != nil {
        fmt.Printf("ERROR: cannot read tar file, error=[%v]\n", err)
        return
    }
    defer reader.Close()

    tarReader := tar.NewReader(reader)
    for {
        header, err := tarReader.Next()
        if err == io.EOF {
            break
        } else if err != nil {
            fmt.Printf("ERROR: cannot read tar file, error=[%v]\n", err)
            return
        }

        j, err := json.Marshal(header)
        if err != nil {
            fmt.Printf("ERROR: cannot parse header, error=[%v]\n", err)
            return
        }
        fmt.Printf("header=%s\n", string(j))

        info := header.FileInfo()
        if info.IsDir() {
            if err = os.MkdirAll(header.Name, 0755); err != nil {
                fmt.Printf("ERROR: cannot mkdir file, error=[%v]\n", err)
                return
            }
        } else {
            if err = os.MkdirAll(path.Dir(header.Name), 0755); err != nil {
                fmt.Printf("ERROR: cannot file mkdir file, error=[%v]\n", err)
                return
            }

            file, err:= os.OpenFile(header.Name, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
            if err != nil {
                fmt.Printf("ERROR: cannot open file, error=[%v]\n", err)
                return
            }
            defer file.Close()

            _, err =io.Copy(file, tarReader)
            if err != nil {
                fmt.Printf("ERROR: cannot write file, error=[%v]\n", err)
                return
            }
        }
    }
}

tar文件的格式定义:
https://www.gnu.org/software/tar/manual/html_node/Standard.html

每一个文件包含一个512字节的头部信息,然后是文件内容;所以对于小文件生成的tar文件反而比原文件大很多。每一个原文件打到tar里面至少包含1024字节(512的头信息,然后是文件内容,不足512字节的后面补零);所以如果原文件大小为一个字节大小,生成的tar文件就会有1024字节大小,结论就是小文件不宜使用tar.gz压缩存储。

使用tar很自然的就会想到gz,因为tar.gz。
下面的模板例子用来处理tar.gz的读写:

读取tar.gz文件内容:

    body := bytes.NewReader([]byte{...})
    gr, err := gzip.NewReader(body)
    tr := tar.NewReader(gr)

    for {
        header, err := tr.Next()
        if err != nil {
            // We only get here if there are no more entries to scan
            break
        }
        HANLD_AN_ENTRY
    }

生成tar.gz文件:

    payload := bytes.NewBuffer(nil)
    gw := gzip.NewWriter(payload)
    tw := tar.NewWriter(gw)

    for _, file := range files {
          info, err := os.Stat(file)
          header, err := tar.FileInfoHeader(info, file)
          err = tw.WriteHeader(header);
         fd, err := os.Open(file)
         _, err := io.Copy(tw, bufio.NewReader(fd));
    }

    tw.Close()
    gw.Close()

    write payload.Bytes() into file.

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:CodingCode

查看原文:golang访问tar文件

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2044 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传