zip
zip包提供了zip档案文件的读写服务。
本包不支持跨硬盘的压缩。
Constants
const (
Store uint16 = 0 // 不压缩
Deflate uint16 = 8 // deflate 压缩
)
预定义压缩算法
Variables
var (
ErrFormat = errors.New("zip: not a valid zip file") // 非正经的zip文件
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的定义获取细节。
FileInfoHeader方法
func FileInfoHeader(fi os.FileInfo) (*FileHeader, error)
FileInfoHeader返回一个根据fi填写了部分字段的Header。因为os.FileInfo接口的Name方法只返回它描述的文件的无路径名,有可能需要将返回值的Name字段修改为文件的完整路径名。
FileInfo方法
func (h *FileHeader) FileInfo() os.FileInfo
FileInfo返回该Header对应的文件信息。(os.FileInfo类型)
Mode方法
func (h *FileHeader) Mode() (mode os.FileMode)
Mode返回h的权限和模式位。
SetMode方法
func (h *FileHeader) SetMode(mode os.FileMode)
SetMode修改h的权限和模式位。
ModTime方法
func (h *FileHeader) ModTime() time.Time
返回最近一次修改的UTC时间。(精度2s)
Use Modified instead.
SetModTime方法
func (h *FileHeader) SetModTime(t time.Time)
将ModifiedTime和ModifiedDate字段设置为给定的UTC时间。(精度2s)
Use Modified instead.
import (
"archive/zip"
"fmt"
"os"
)
func main() {
fileinfo, err := os.Stat("C:/Users/Administrator/Desktop/test.docx")
if err != nil {
fmt.Println(err)
}
h, err := zip.FileInfoHeader(fileinfo)
if err != nil {
fmt.Println(err)
}
fmt.Println(h.Name, h.Comment, h.CreatorVersion)
// FileInfo
fileinfo2 := h.FileInfo()
fmt.Println(fileinfo2.Name())
// Mode
fmt.Println(h.Mode())
// SetMode
h.SetMode(755)
fmt.Println(h.Mode())
// Deprecated: Use Modified instead.
//modTime := h.ModTime()
//fmt.Println(modTime)
//
// Deprecated: Use Modified instead.
//h.SetModTime(time.Now())
//fmt.Println(h.ModTime())
fmt.Println(h.Modified)
h.Modified = time.Now()
fmt.Println(h.Modified)
}
type File
type File struct {
FileHeader
zip *Reader
zipr io.ReaderAt
zipsize int64
headerOffset int64
}
DataOffset方法
func (f *File) DataOffset() (offset int64, err error)
DataOffset返回文件的可能存在的压缩数据相对于zip文件起始的偏移量。大多数调用者应使用Open代替,该方法会主动解压缩数据并验证校验和。
Open方法
func (f *File) Open() (rc io.ReadCloser, err error)
Open方法返回一个io.ReadCloser接口,提供读取文件内容的方法。可以同时读取多个文件。
type Reader
type Reader struct {
r io.ReaderAt
File []*File
Comment string
decompressors map[uint16]Decompressor
}
NewReader方法
func NewReader(r io.ReaderAt, size int64) (*Reader, error)
NewReader返回一个从r读取数据的*Reader,r被假设其大小为size字节
type ReadCloser
type ReadCloser struct {
f *os.File
Reader
}
OpenReader方法
func OpenReader(name string) (*ReadCloser, error)
OpenReader会打开name指定的zip文件并返回一个*ReadCloser。
Close方法
func (rc *ReadCloser) Close() error
Close关闭zip文件,使它不能用于I/O。
func main() {
const File = "C:/Users/Administrator/Downloads/test001.zip"
const dir = "C:/Users/Administrator/Downloads/test001/"
os.Mkdir(dir, 0777) //创建一个目录
or, err := zip.OpenReader(File) //读取zip文件
if err != nil {
fmt.Println(err)
}
defer or.Close()
for _, file := range or.File {
rc, err := file.Open()
if err != nil {
fmt.Println(err)
}
f, err := os.Create(dir + file.Name)
if err != nil {
fmt.Println(err)
}
defer f.Close()
n, err := io.Copy(f, rc)
if err != nil {
fmt.Println(err)
}
fmt.Println(n)
}
}
type Writer
// Writer implements a zip file writer.
type Writer struct {
cw *countWriter
dir []*header
last *fileWriter
closed bool
compressors map[uint16]Compressor
comment string
// testHookCloseSizeOffset if non-nil is called with the size
// of offset of the central directory at Close.
testHookCloseSizeOffset func(size, offset uint64)
}
NewWriter方法
func NewWriter(w io.Writer) *Writer
NewWriter创建并返回一个将zip文件写入w的*Writer。
CreateHeader方法
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error)
使用给出的*FileHeader来作为文件的元数据添加一个文件进zip文件。本方法返回一个io.Writer接口(用于写入新添加文件的内容)。新增文件的内容必须在下一次调用CreateHeader、Create或Close方法之前全部写入。
Create方法
func (w *Writer) Create(name string) (io.Writer, error)
使用给出的文件名添加一个文件进zip文件。本方法返回一个io.Writer接口(用于写入新添加文件的内容)。文件名必须是相对路径,不能以设备或斜杠开始,只接受'/'作为路径分隔。新增文件的内容必须在下一次调用CreateHeader、Create或Close方法之前全部写入。
Close方法
func (w *Writer) Close() error
Close方法通过写入中央目录关闭该*Writer。本方法不会也没办法关闭下层的io.Writer接口。
func main() {
const dir = "C:/Users/Administrator/Downloads/test001/"
//获取源文件列表
f, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Println(err)
}
fzip, _ := os.Create("C:/Users/Administrator/Downloads/test001/test00001.zip")
w := zip.NewWriter(fzip)
defer w.Close()
for _, file := range f {
fw, _ := w.Create(file.Name())
filecontent, err := ioutil.ReadFile(dir + file.Name())
if err != nil {
fmt.Println(err)
}
n, err := fw.Write(filecontent)
if err != nil {
fmt.Println(err)
}
fmt.Println(n)
}
}
有疑问加站长微信联系(非本文作者)