preface

In actual business, we can use the form of ZIP file to achieve file archiving, volume compression and other operations. The Archive package in Go’s standard library also provides archiving and decompression of tar and ZIP files. This article will first explain the zip format file.

define

constant

const (
	Store   uint16 = 0 // no compression
	Deflate uint16 = 8 // DEFLATE compressed
)
Copy the code

The ZIP package provides support for two compression algorithms

Store: without compression

Deflate: A compression method using the Deflate algorithm, in which Deflate is a lossless data compression algorithm using both LZ77 algorithm and Huffman Coding.

FileHeader

type FileHeader struct {
    // Name is the file Name. It must be a relative path and cannot start with a device or a slash. Only '/' is accepted as a path separator
    Name string
    CreatorVersion     uint16
    ReaderVersion      uint16
    Flags              uint16
    Method             uint16
    ModifiedTime       uint16 / / ms-dos time
    ModifiedDate       uint16 / / date of ms-dos
    CRC32              uint32
    CompressedSize64   uint64
    UncompressedSize64 uint64
    Extra              []byte
    ExternalAttrs      uint32 // Its meaning depends on CreatorVersion
    Comment            string
}
Copy the code
  • func FileInfoHeader(fi os.FileInfo) (*FileHeader, error)

Creates and returns an FileHeader containing partial information, based on an argument of type os.FileInfo

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

Returns an os.fileInfo generated from the FileHeader information.

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

Gets the last modification time

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

Set change time

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

Returns the file type and permission information of the file corresponding to FileHeader

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

Set the file type and permission information of the file corresponding to FileHeader

File

type File struct {
    FileHeader
    // contains filtered or unexported fields
}
Copy the code
  • func (f *File) Open() (rc io.ReadCloser, err error)

The Open method returns an IO.ReadCloser interface that provides a way to read the contents of a file. Multiple files can be read simultaneously.

The compression

Writer

func NewWriter(w io.Writer) *Writer  

func (w *Writer) Close(a) error

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

func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) 
Copy the code
  • NewWriter creates and returns a *Writer that writes the zip file to w
  • The Create method passes in the file name added to the zip file and returns an IO.Writer to write to. The name argument accepts only relative paths.
  • CreateHeader Creates a file in the add zip file using the FileHeader type, and also returns an IO.Writer to write to.

Example

func Zip(filePath string, w io.ReadWriter) error {
    f, err := ioutil.ReadDir(filePath)
    iferr ! =nil {
        fmt.Println(err)
    }
    zipFile, _ := os.Create("test.zip")
    w := zip.NewWriter(zipFile)
    defer w.Close()
    for _, file := range f {
        fw, _ := w.Create(file.Name())
        filecontent, err := ioutil.ReadFile(filePath + file.Name())
        iferr ! =nil {
            fmt.Println(err)
        }
        n, err := fw.Write(filecontent)
        iferr ! =nil {
            fmt.Println(err)
        }
    }
}

Copy the code

Unpack the

Reader

type Reader struct {
    r             io.ReaderAt
    File          []*File
    Comment       string
    decompressors map[uint16]Decompressor
}
type ReadCloser struct {
    Reader
    f *os.File
}

func OpenReader(name string) (*ReadCloser, error) 
func NewReader(r io.ReaderAt, size int64) (*Reader, error) 
func (rc *ReadCloser) Close(a) error/ / closeReadCloser
Copy the code
  • With OpenReader, you pass in the file name and return an object of type ReadCloser for that file
  • NewReader returns a *Reader that reads data from r, which is assumed to be size bytes.

Example

func UnZip(fileName, filePath string, w io.ReadWriter) error {
    f, err := zip.OpenReader(filePath + "/" + fileName) // Read the zip file
    iferr ! =nil {
        fmt.Println(err)
    }
    defer f.Close()
    for _, file := range f.File {
        rc, err := file.Open()
        iferr ! =nil {
            fmt.Println(err)
        }

        f, err := os.Create(filePath + file.Name)
        iferr ! =nil {
            fmt.Println(err)
        }
        defer f.Close()
        n, err := io.Copy(f, rc)
        iferr ! =nil {
            fmt.Println(err)
        }
    }
}

Copy the code