# package tar

`import "archive/tar"`

tar包实现了tar格式压缩文件的存取。本包目标是覆盖大多数tar的变种，包括GNU和BSD生成的tar文件。

参见：

    http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
    http://www.gnu.org/software/tar/manual/html_node/Standard.html
    http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html

Example

    // Create a buffer to write our archive to.
    buf := new(bytes.Buffer)
    // Create a new tar archive.
    tw := tar.NewWriter(buf)
    // Add some files to the archive.
    var files = []struct {
        Name, Body string
    }{
        {"readme.txt", "This archive contains some text files."},
        {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
        {"todo.txt", "Get animal handling licence."},
    }
    for _, file := range files {
        hdr := &tar.Header{
            Name: file.Name,
            Size: int64(len(file.Body)),
        }
        if err := tw.WriteHeader(hdr); err != nil {
            log.Fatalln(err)
        }
        if _, err := tw.Write([]byte(file.Body)); err != nil {
            log.Fatalln(err)
        }
    }
    // Make sure to check the error on Close.
    if err := tw.Close(); err != nil {
        log.Fatalln(err)
    }
    // Open the tar archive for reading.
    r := bytes.NewReader(buf.Bytes())
    tr := tar.NewReader(r)
    // Iterate through the files in the archive.
    for {
        hdr, err := tr.Next()
        if err == io.EOF {
            // end of tar archive
            break
        }
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Printf("Contents of %s:\n", hdr.Name)
        if _, err := io.Copy(os.Stdout, tr); err != nil {
            log.Fatalln(err)
        }
        fmt.Println()
    }

Output:

    Contents of readme.txt:
    This archive contains some text files.
    Contents of gopher.txt:
    Gopher names:
    George
    Geoffrey
    Gonzo
    Contents of todo.txt:
    Get animal handling licence.

## Constants

    const (
        // 类型
        TypeReg           = '0'    // 普通文件
        TypeRegA          = '\x00' // 普通文件
        TypeLink          = '1'    // 硬链接
        TypeSymlink       = '2'    // 符号链接
        TypeChar          = '3'    // 字符设备节点
        TypeBlock         = '4'    // 块设备节点
        TypeDir           = '5'    // 目录
        TypeFifo          = '6'    // 先进先出队列节点
        TypeCont          = '7'    // 保留位
        TypeXHeader       = 'x'    // 扩展头
        TypeXGlobalHeader = 'g'    // 全局扩展头
        TypeGNULongName   = 'L'    // 下一个文件记录有个长名字
        TypeGNULongLink   = 'K'    // 下一个文件记录指向一个具有长名字的文件
        TypeGNUSparse     = 'S'    // 稀疏文件
    )

## Variables

    var (
        ErrWriteTooLong    = errors.New("archive/tar: write too long")
        ErrFieldTooLong    = errors.New("archive/tar: header field too long")
        ErrWriteAfterClose = errors.New("archive/tar: write after close")
    )

    var (
        ErrHeader = errors.New("archive/tar: invalid tar header")
    )

## type Header

    type Header struct {
        Name       string    // 记录头域的文件名
        Mode       int64     // 权限和模式位
        Uid        int       // 所有者的用户ID
        Gid        int       // 所有者的组ID
        Size       int64     // 字节数（长度）
        ModTime    time.Time // 修改时间
        Typeflag   byte      // 记录头的类型
        Linkname   string    // 链接的目标名
        Uname      string    // 所有者的用户名
        Gname      string    // 所有者的组名
        Devmajor   int64     // 字符设备或块设备的major number
        Devminor   int64     // 字符设备或块设备的minor number
        AccessTime time.Time // 访问时间
        ChangeTime time.Time // 状态改变时间
        Xattrs     map[string]string
    }

Header代表tar档案文件里的单个头。Header类型的某些字段可能未使用。

### func FileInfoHeader

    func FileInfoHeader(fi os.FileInfo, link string) (*Header, error)

FileInfoHeader返回一个根据fi填写了部分字段的Header。 如果fi描述一个符号链接，FileInfoHeader函数将link参数作为链接目标。如果fi描述一个目录，会在名字后面添加斜杠。因为os.FileInfo接口的Name方法只返回它描述的文件的无路径名，有可能需要将返回值的Name字段修改为文件的完整路径名。

### func (*Header) FileInfo

    func (h *Header) FileInfo() os.FileInfo

FileInfo返回该Header对应的文件信息。（os.FileInfo类型）

## type Reader

    type Reader struct {
        // 内含隐藏或非导出字段
    }

Reader提供了对一个tar档案文件的顺序读取。一个tar档案文件包含一系列文件。Next方法返回档案中的下一个文件（包括第一个），返回值可以被视为io.Reader来获取文件的数据。

### func NewReader

    func NewReader(r io.Reader) *Reader

NewReader创建一个从r读取的Reader。

### func (*Reader) Next

    func (tr *Reader) Next() (*Header, error)

转入tar档案文件下一记录，它会返回下一记录的头域。

### func (*Reader) Read

    func (tr *Reader) Read(b []byte) (n int, err error)

从档案文件的当前记录读取数据，到达记录末端时返回(0, EOF)，直到调用Next方法转入下一记录。

## type Writer

    type Writer struct {
        // 内含隐藏或非导出字段
    }

Writer类型提供了POSIX.1格式的tar档案文件的顺序写入。一个tar档案文件包含一系列文件。调用WriteHeader来写入一个新的文件，然后调用Write写入文件的数据，该记录写入的数据不能超过hdr.Size字节。

### func NewWriter

    func NewWriter(w io.Writer) *Writer

NewWriter创建一个写入w的*Writer。

### func (*Writer) WriteHeader

    func (tw *Writer) WriteHeader(hdr *Header) error

WriteHeader写入hdr并准备接受文件内容。如果不是第一次调用本方法，会调用Flush。在Close之后调用本方法会返回ErrWriteAfterClose。

### func (*Writer) Write

    func (tw *Writer) Write(b []byte) (n int, err error)

Write向tar档案文件的当前记录中写入数据。如果写入的数据总数超出上一次调用WriteHeader的参数hdr.Size字节，返回ErrWriteTooLong错误。

### func (*Writer) Flush

    func (tw *Writer) Flush() error

Flush结束当前文件的写入。（可选的）

### func (*Writer) Close

    func (tw *Writer) Close() error

Close关闭tar档案文件，会将缓冲中未写入下层的io.Writer接口的数据刷新到下层。