首页 > 其他分享 >golang 压缩包解压问题汇总

golang 压缩包解压问题汇总

时间:2024-05-13 10:42:26浏览次数:27  
标签:解压 return nil err golang file os 压缩包 string

解压代码

package main

import (
	"archive/zip"
	"bytes"
	"fmt"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

func main() {
	fileInfo, err := Unzip("./test.zip", "./test")

	fmt.Println(err)
	fmt.Println(fileInfo)

}

func Unzip(zipFile string, destDir string) ([]string, error) {
	// 获取压缩包信息
	zipReader, err := zip.OpenReader(zipFile)
	if err != nil {
		return []string{}, err
	}
	defer zipReader.Close()
	// 解压目录是否存在,不存在则创建
	if _, err = os.Stat(destDir); os.IsNotExist(err) {
		err = os.MkdirAll(destDir, os.ModePerm)
		if err != nil {
			return []string{}, err
		}
	}
	// 解压后全部文件路径
	var filePathSlice []string
	for _, file := range zipReader.File { // 循环获取压缩包里的文件信息
		path, err := func() (string, error) {
			var decodeName string
			if file.Flags == 0 { //如果标致位是0  则是默认的本地编码   默认为gbk
				i := bytes.NewReader([]byte(file.Name))
				decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
				content, _ := ioutil.ReadAll(decoder)
				decodeName = string(content)
			} else {
				decodeName = file.Name
			}
			path := filepath.Join(destDir, decodeName)
			// 如果是目录,就创建目录
			if file.FileInfo().IsDir() {
				if err = os.MkdirAll(path, file.Mode()); err != nil {
					return "", err
				}
				return path, nil
			}
			if err = os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
				return "", err
			}
			// 获取到 Reader
			fr, err := file.Open()
			if err != nil {
				return "", err
			}
			defer fr.Close()
			// 创建要写出的文件对应的 Write
			fw, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, file.Mode())
			if err != nil {
				return "", err
			}
			defer fw.Close()
			_, err = io.Copy(fw, fr)
			if err != nil {
				return "", err
			}
			return path, nil
		}()
		if err != nil {
			return []string{}, err
		} else {
			filePathSlice = append(filePathSlice, path)
		}
	}
	return filePathSlice, nil
}

注意问题

中文文件名解压乱码

原因:winrar压缩时,默认采用本地编码方式来进行压缩。在中国,本地编码方式一般是GBK。而我们知道go语言字符串都是utf-8格式的,所以有可能出现乱码的情况

解决方案:判定文件名编码方式,如果为GBK,则转换GBK=》utf-8

对应代码:

if file.Flags == 0 { //如果标致位是0  则是默认的本地编码   默认为gbk
	i := bytes.NewReader([]byte(file.Name))
	decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
	content, _ := ioutil.ReadAll(decoder)
	decodeName = string(content)
} else {
	decodeName = file.Name
}

参考文章:https://www.php.cn/faq/438093.html

获取压缩文件信息时,不能获取到目录信息

原因:Windows的压缩功能(如“发送到”>“压缩(zipped)文件夹”)在处理只有一个文件的文件夹时,可能会简化压缩过程,以提高效率和节省存储空间。在这种情况下,它不会记录空的外层文件夹,而是直接将文件作为压缩包内的顶级元素。这是因为它认为保留一个只包含一个文件的空文件夹结构没有必要,这样做可以减少压缩文件的大小和解压后的复杂性。

解决方案:获取文件信息后,多做一步确保文件夹存在

对应代码:

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

标签:解压,return,nil,err,golang,file,os,压缩包,string
From: https://www.cnblogs.com/xingzr/p/18188626

相关文章

  • golang channel 封装
    对于closed或nil通道,规则如下:无论收发,nil通道都会阻塞。不能关闭nil通道。重复关闭通道,引发panic!向已关闭通道发送数据,引发panic!从已关闭通道接收数据,返回缓冲数据或零值。nil通道是指没有make的变量。鉴于通道关闭后,所有基于此的阻塞都被解除,可用作通知。没......
  • BeyondCompare破解版-解压即用
    链接:https://pan.baidu.com/s/1vGKnPh6WMhk_bYJyJyKqXw提取码:dasf打开软件找到帮助——关于beyondcompare,如下破解成功。操作简单,能正常使用原文链接:https://blog.csdn.net/sinat_39684057/article/details/98053227......
  • 【golang】go语言学习需要注意的点
     (学习可参考菜鸟教程:https://www.runoob.com/go/go-basic-syntax.html) 1.Go编译生成的exe程序在后台运行(不闪过console窗口)gobuild-ldflags"-s-w-H=windowsgui"-s省略符号表和调试信息-wOmittheDWARFsymboltable省略DWARF符号表-Hwindowsgui不打印信......
  • golang项目包管理(go module模式)
     修改GO111MODULE和GOPROXYexportGO111MODULE=onexportGOPROXY=https://goproxy.io#GO111MODULE默认为auto,当项目存在go.mod,会自动启用gomodule模式。这里还是直接开启比较好。初始化go.modgomodinit安装依赖goget依赖包#下载的依赖包放在GOPATH下pkg下的m......
  • Golang gin 框架使用 MongoDB 进行多表联查,以及分组查询
    主要针对gin框架中如何使用假设两张表order表{"_id":ObjectId("65aa2b2203abce203bbe3c7a"),"name":"骆驼祥子","route":"/test/v2/desktop","bookshelf":"03"}orderRemark表{......
  • golang生成二维码图片,支持图片下方增加多行居中文本
    golang生成二维码图片,支持图片下方增加多行居中文本效果工具类代码packageUtilsimport( "bytes" "fmt" "github.com/golang/freetype/truetype" "github.com/skip2/go-qrcode" "golang.org/x/image/font" "golang.org/x/image/math......
  • golang 获得一个结构体的字节大小
    golang的内存占用是如何构成的呢?unsafe.SizeOf()转载:如何在Go中获取变量的内存大小?--CSDN问答如果传递一个未初始化的变量,unsafe.Sizeof()与reflect.Type.Size()将只返回传递的变量的类型的大小,并不递归地遍历数据结构并增加所指向变量的大小。切片是一个相对简单的结构体st......
  • 用Golang做一个永久阻塞,有哪些小技巧 ?
    用Golang做一个永久阻塞,有哪些小技巧?磊丰 Go语言圈 2024-05-0608:30 广东 听全文Go语言圈Go语言开发者的学习好助手,分享Go语言知识,技术技巧,学习与交流Go语言开发经验,互动才有助于技术的提升,每天5分钟,助你GO语言技术快乐成长159篇原创内容公众号......
  • 为什么我要使得GOLang重写SAAS(软件即服务)服务端
    引言“道”在中国哲学中,是一个重要的概念,表示“终极真理”。“道”这一概念,不单为哲学流派诸子百家所重视,也被宗教流派道教等所使用。大道至简的意思就是大道理是极其简单的,简单到一两句话就能说明白。所谓“真传一句话,假传万卷书”。正文在开启独立创作之路之前,我主要用不用......
  • Golang:go-humanize将文件大小转换成Kb、Mb、Gb适合人类阅读的单位
    Golang:go-humanize将文件大小转换成Kb、Mb、Gb适合人类阅读的单位原创 吃个大西瓜 CodingBigTree 2024-05-0408:30 云南​最近去了昆明的教场中路体验了满屏蓝花楹,感受到了梦幻般的世界,随手拍了一张图,分享给大家,有时间可以去一趟,体验一次,顺便说一下,美女很多喔 ......