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)
参考