生成压缩包

zip

package lib

import (
	"archive/zip"
	ezip "github.com/alexmullins/zip"
	"github.com/cilidm/toolbox/str"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"
)

func EncryptZip(src, dst, passwd string, blackFile []string) error {
	zipfile, err := os.Create(dst)
	if err != nil {
		return err
	}
	defer zipfile.Close()
	archive := ezip.NewWriter(zipfile)
	defer archive.Close()
	filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if runtime.GOOS == "windows" {
			src = strings.ReplaceAll(src, "\\", "/")
			path = strings.ReplaceAll(path, "\\", "/")
		}
		if str.IsContain(blackFile, info.Name()) {
			return nil
		}
		header, err := ezip.FileInfoHeader(info)
		if err != nil {
			return err
		}
		header.Name = strings.ReplaceAll(path, src, "")
		if info.IsDir() {
			header.Name += "/"
		} else {
			header.Method = zip.Deflate
		}
		// 设置密码
		header.SetPassword(passwd)
		writer, err := archive.CreateHeader(header)
		if err != nil {
			return err
		}
		if !info.IsDir() {
			file, err := os.Open(path)
			if err != nil {
				return err
			}
			defer file.Close()
			_, err = io.Copy(writer, file)
		}
		return err
	})
	return err
}

unzip

package lib

import (
	"bytes"
	"fmt"
	"github.com/alexmullins/zip"
	"github.com/cilidm/toolbox/str"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
)


//DeCompressZip 解压zip包
func DeCompressZip(zipFile, dest, passwd string, offset int64) error {
	zr, err := zip.OpenReader(zipFile)
	if err != nil {
		return err
	}
	defer zr.Close()

	for _, f := range zr.File {
		if passwd != "" {
			f.SetPassword(passwd)
		}
		var decodeName string
		if f.Flags == 1 {
			//如果标致位是1  则是默认的本地编码   默认为gbk
			i := bytes.NewReader([]byte(f.Name))
			decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
			content, _ := ioutil.ReadAll(decoder)
			decodeName = string(content)
		} else {
			//如果标志为是 0 << 11也就是 2048  则是utf-8编码
			decodeName = f.Name
		}
		fpath := filepath.Join(dest, decodeName)
		if f.FileInfo().IsDir() {
			os.MkdirAll(fpath, os.ModePerm)
			continue
		}

		if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
			return err
		}

		inFile, err := f.Open()
		if err != nil {
			return err
		}

		outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
		if err != nil {
			inFile.Close()
			return err
		}

		_, err = io.Copy(outFile, inFile)
		inFile.Close()
		outFile.Close()
		if err != nil {
			return err
		}
	}
	return nil
}

func DeCompressZipByte(zipFile, passwd string, offset int64) (map[string][]byte, error) {
	zr, err := zip.OpenReader(zipFile)
	if err != nil {
		return nil, err
	}
	defer zr.Close()
	var chunkMap = make(map[string][]byte)
	for _, f := range zr.File {
		if passwd != "" {
			f.SetPassword(passwd)
		}
		var decodeName string
		if f.Flags == 1 {
			//如果标致位是1  则是默认的本地编码   默认为gbk
			i := bytes.NewReader([]byte(f.Name))
			decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
			content, _ := ioutil.ReadAll(decoder)
			decodeName = string(content)
		} else {
			//如果标志为是 0 << 11也就是 2048  则是utf-8编码
			decodeName = f.Name
		}

		inFile, err := f.Open()
		if err != nil {
			return nil, err
		}
		defer inFile.Close()

		var chunk []byte
		buf := make([]byte, 1024)
		for {
			//从file读取到buf中
			n, err := inFile.Read(buf)
			if err != nil && err != io.EOF {
				fmt.Println("read buf fail", err)
				break
			}
			//说明读取结束
			if n == 0 {
				break
			}
			//读取到最终的缓冲区中
			chunk = append(chunk, buf[:n]...)
		}
		chunkMap[decodeName] = chunk
	}
	return chunkMap, nil
}

func DeCompressZipInfo(zipFile, passwd string, offset int64) ([]zip.File, error) {
	zr, err := zip.OpenReader(zipFile)
	if err != nil {
		return nil, err
	}
	defer zr.Close()

	blackName := []string{""}
	var fileMap []zip.File
	for _, f := range zr.File {
		if passwd != "" {
			f.SetPassword(passwd)
		}
		var decodeName string
		if f.Flags == 1 {
			//如果标致位是1  则是默认的本地编码   默认为gbk
			i := bytes.NewReader([]byte(f.Name))
			decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
			content, _ := ioutil.ReadAll(decoder)
			decodeName = string(content)
		} else {
			//如果标志为是 0 << 11也就是 2048  则是utf-8编码
			decodeName = f.Name
		}
		fmt.Println(decodeName)
		if str.IsContain(blackName, decodeName) {
			fmt.Println(decodeName, "is in black name")
			continue
		}
		f.Name = decodeName
		fileMap = append(fileMap, *f)
	}
	return fileMap, nil
}

func GetZipFileByName(zipFile, passwd, name string) ([]byte, error) {
	zipr, err := zip.OpenReader(zipFile)
	if err != nil {
		log.Fatal(err)
	}
	defer zipr.Close()

	var chunkMap []byte
	for _, f := range zipr.File {
		if passwd != "" {
			f.SetPassword(passwd)
		}

		if f.Name != name {
			continue
		}

		inFile, err := f.Open()
		if err != nil {
			return nil, err
		}
		defer inFile.Close()

		var chunk []byte
		buf := make([]byte, 1024)
		for {
			//从file读取到buf中
			n, err := inFile.Read(buf)
			if err != nil && err != io.EOF {
				fmt.Println("read buf fail", err)
				break
			}
			//说明读取结束
			if n == 0 {
				break
			}
			//读取到最终的缓冲区中
			chunk = append(chunk, buf[:n]...)
		}
		chunkMap = chunk
		break
	}
	return chunkMap, nil
}

go mod

module zip

go 1.16

require (
	github.com/alexmullins/zip v0.0.0-20180717182244-4affb64b04d0
	github.com/cilidm/toolbox v0.0.0-20210603034745-e82616c96f7b
	golang.org/x/text v0.3.7
)

最后更新于