# package zip

`import "archive/zip"`

zip包提供了zip档案文件的读写服务。参见http://www.pkware.com/documents/casestudies/APPNOTE.TXT

本包不支持跨硬盘的压缩。

关于ZIP64：

为了向下兼容，FileHeader同时拥有32位和64位的Size字段。64位字段总是包含正确的值，对普通格式的档案未见它们的值是相同的。对zip64格式的档案文件32位字段将是0xffffffff，必须使用64位字段。

## Constants

    const (
        Store   uint16 = 0
        Deflate uint16 = 8
    )

预定义压缩算法。

## Variables

    var (
        ErrFormat    = errors.New("zip: not a valid zip file")
        ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
        ErrChecksum  = errors.New("zip: checksum error")
    )

## type Compressor

    type Compressor func(io.Writer) (io.WriteCloser, error)

Compressor函数类型会返回一个io.WriteCloser，该接口会将数据压缩后写入提供的接口。关闭时，应将缓冲中的数据刷新到下层接口中。

## type Decompressor

    type Decompressor func(io.Reader) io.ReadCloser

Decompressor函数类型会返回一个io.ReadCloser， 该接口的Read方法会将读取自提供的接口的数据提前解压缩。程序员有责任在读取结束时关闭该io.ReadCloser。

## func RegisterCompressor

    func RegisterCompressor(method uint16, comp Compressor)

RegisterCompressor使用指定的方法ID注册一个Compressor类型函数。常用的方法Store和Deflate是内建的。

## func RegisterDecompressor

    func RegisterDecompressor(method uint16, d Decompressor)

RegisterDecompressor使用指定的方法ID注册一个Decompressor类型函数。

## type FileHeader

    type FileHeader struct {
        // Name是文件名，它必须是相对路径，不能以设备或斜杠开始，只接受'/'作为路径分隔符
        Name string
        CreatorVersion     uint16
        ReaderVersion      uint16
        Flags              uint16
        Method             uint16
        ModifiedTime       uint16 // MS-DOS时间
        ModifiedDate       uint16 // MS-DOS日期
        CRC32              uint32
        CompressedSize     uint32 // 已弃用；请使用CompressedSize64
        UncompressedSize   uint32 // 已弃用；请使用UncompressedSize64
        CompressedSize64   uint64
        UncompressedSize64 uint64
        Extra              []byte
        ExternalAttrs      uint32 // 其含义依赖于CreatorVersion
        Comment            string
    }

FileHeader描述zip文件中的一个文件。参见zip的定义获取细节。

### func FileInfoHeader

    func FileInfoHeader(fi os.FileInfo) (*FileHeader, error)

FileInfoHeader返回一个根据fi填写了部分字段的Header。因为os.FileInfo接口的Name方法只返回它描述的文件的无路径名，有可能需要将返回值的Name字段修改为文件的完整路径名。

### func (*FileHeader) FileInfo

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

FileInfo返回一个根据h的信息生成的os.FileInfo。

### func (*FileHeader) Mode

    func (h *FileHeader) Mode() (mode os.FileMode)

Mode返回h的权限和模式位。

### func (*FileHeader) SetMode

    func (h *FileHeader) SetMode(mode os.FileMode)

SetMode修改h的权限和模式位。

### func (*FileHeader) ModTime

    func (h *FileHeader) ModTime() time.Time

返回最近一次修改的UTC时间。（精度2s）

### func (*FileHeader) SetModTime

    func (h *FileHeader) SetModTime(t time.Time)

将ModifiedTime和ModifiedDate字段设置为给定的UTC时间。（精度2s）

## type File

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

### func (*File) DataOffset

    func (f *File) DataOffset() (offset int64, err error)

DataOffset返回文件的可能存在的压缩数据相对于zip文件起始的偏移量。大多数调用者应使用Open代替，该方法会主动解压缩数据并验证校验和。

### func (*File) Open

    func (f *File) Open() (rc io.ReadCloser, err error)

Open方法返回一个io.ReadCloser接口，提供读取文件内容的方法。可以同时读取多个文件。

## type Reader

    type Reader struct {
        File    []*File
        Comment string
        // 内含隐藏或非导出字段
    }

Example

    // Open a zip archive for reading.
    r, err := zip.OpenReader("testdata/readme.zip")
    if err != nil {
        log.Fatal(err)
    }
    defer r.Close()
    // Iterate through the files in the archive,
    // printing some of their contents.
    for _, f := range r.File {
        fmt.Printf("Contents of %s:\n", f.Name)
        rc, err := f.Open()
        if err != nil {
            log.Fatal(err)
        }
        _, err = io.CopyN(os.Stdout, rc, 68)
        if err != nil {
            log.Fatal(err)
        }
        rc.Close()
        fmt.Println()
    }

Output:

    Contents of README:
    This is the source code repository for the Go programming language.

### func NewReader

    func NewReader(r io.ReaderAt, size int64) (*Reader, error)

NewReader返回一个从r读取数据的*Reader，r被假设其大小为size字节。

## type ReadCloser

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

### func OpenReader

    func OpenReader(name string) (*ReadCloser, error)

OpenReader会打开name指定的zip文件并返回一个*ReadCloser。

### func (*ReadCloser) Close

    func (rc *ReadCloser) Close() error

Close关闭zip文件，使它不能用于I/O。

## type Writer

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

Writer类型实现了zip文件的写入器。

Example

    // Create a buffer to write our archive to.
    buf := new(bytes.Buffer)
    // Create a new zip archive.
    w := zip.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.\nWrite more examples."},
    }
    for _, file := range files {
        f, err := w.Create(file.Name)
        if err != nil {
            log.Fatal(err)
        }
        _, err = f.Write([]byte(file.Body))
        if err != nil {
            log.Fatal(err)
        }
    }
    // Make sure to check the error on Close.
    err := w.Close()
    if err != nil {
        log.Fatal(err)
    }

### func NewWriter

    func NewWriter(w io.Writer) *Writer

NewWriter创建并返回一个将zip文件写入w的*Writer。

### func (*Writer) CreateHeader

    func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error)

使用给出的*FileHeader来作为文件的元数据添加一个文件进zip文件。本方法返回一个io.Writer接口（用于写入新添加文件的内容）。新增文件的内容必须在下一次调用CreateHeader、Create或Close方法之前全部写入。

### func (*Writer) Create

    func (w *Writer) Create(name string) (io.Writer, error)

使用给出的文件名添加一个文件进zip文件。本方法返回一个io.Writer接口（用于写入新添加文件的内容）。文件名必须是相对路径，不能以设备或斜杠开始，只接受'/'作为路径分隔。新增文件的内容必须在下一次调用CreateHeader、Create或Close方法之前全部写入。

### func (*Writer) Close

    func (w *Writer) Close() error

Close方法通过写入中央目录关闭该*Writer。本方法不会也没办法关闭下层的io.Writer接口。