Golang基础编程: archive/zip包

toLinux

统一使用路径符 "/", 包含"\"替换为"/"

func toLinux(basePath string) string {
	return strings.ReplaceAll(basePath, "\\", "/")
}

Zip 压缩

    参数 1 :  压缩文件(目录)路径+名

    参数2 :   往哪里写, 本地压缩传文件变量, 压缩后将流传到其它电脑主机使用传入bytes.buffer  (即包含io.Writer接口的结构变量都可)

func Zip(fp string, w io.ReadWriter) error {
	archive := zip.NewWriter(w)
	defer archive.Close()

	linuxFilePath := toLinux(fp)
	filepath.Walk(linuxFilePath, func(path string, info os.FileInfo, err error) error {

		var linuxPath = toLinux(path)
		if linuxPath == linuxFilePath { return nil }

		header, _ := zip.FileInfoHeader(info)
		header.Name = strings.TrimPrefix(linuxPath, linuxFilePath + "/")

		if info.IsDir() {
			header.Name += `/`
		} else {
			// 设置:zip的文件压缩算法
			header.Method = zip.Deflate
		}
		// 创建:压缩包头部信息
		writer, _ := archive.CreateHeader(header)
		if !info.IsDir() {
			file, _ := os.Open(linuxPath)
			defer file.Close()
			io.Copy(writer, file)
		}
		return nil
	})

	return nil
}

Unzip

  参数1: 解压到哪个路径下

  参数2: file/bytes.buffer 等待io.Reader接口的结构类型变量

func Unzip(basePath string, r io.Reader) error {
	/* 创建属于解压的缓存目录 */
	var dir = path.Join(os.TempDir(), "zip")
	os.MkdirAll(dir, 0666)

	/* 创建解压缓存文件 */
	f, e := ioutil.TempFile(dir, "zip")
	if nil != e { return e }
	defer func() {
		f.Close()
		os.RemoveAll(f.Name())
	}()

	_, e = io.Copy(f, r)
	if nil != e { return e }

	return unzip(basePath, f)
}

func unzip(basePath string, f *os.File) error {
	var reader *zip.Reader
	var stat, _ = f.Stat()
	reader, e := zip.NewReader(f, stat.Size())
	if nil != e { return e }
	os.MkdirAll(basePath, 0666) // 确保解压目录存在

	for _, info := range reader.File {
		var fp = toLinux(path.Join(basePath, info.Name))
		if info.FileInfo().IsDir() {
			if e := os.MkdirAll(fp, info.FileInfo().Mode()); nil != e { return e }
			continue
		}

		readcloser, e := info.Open()
		if nil != e { return e }

		b, e := ioutil.ReadAll(readcloser)
		if nil != e { return e }
		readcloser.Close()

		if e := ioutil.WriteFile(fp, b, info.FileInfo().Mode()); nil != e { return e }
	}
	return nil
}

func main() {
    /* 1. 从压缩文件解压 */
	file, e := os.Open("./hello.zip")
	if nil != e { return }
	defer file.Close()
	Unzip("./hello", file)
	
	
	bs, e := ioutil.ReadAll(file)
	if nil != e { return }
	
	/* 2. 从存放压缩字节的buffer数据解压 */
	buffer = bytes.NewBuffer(bs)
	Unzip("./hello1", buffer)
}

问题

解压的时候报错 The system cannot find the path specified.

因为使用相对路径, 导致walk时出现地址不匹配 ./dizhi 跟 dizhi 不匹配 TrimPrefix没将地址替换掉

(1) Zip函数去掉 if linuxPath == linuxFilePath { return nil }

        按目录层级进行压缩

   (2) 将绝对路径转化成绝对路径

       linuxFilePath := toLinux(fp) => linuxFilePath := ToAbsolutePath(fp)

      参考

      https://blog.csdn.net/halo_hsuh/article/details/107168060

猜你喜欢

转载自blog.csdn.net/halo_hsuh/article/details/107159346