feat(filex): 自 go-hua/common 迁入文件目录工具并独立成包
- 运行目录定位、路径存在性、带进度回调下载、Zip 打包/解压(兼容 GBK 中文文件名) - 附单元测试、examples/filex 例程与包 README
This commit is contained in:
+120
@@ -0,0 +1,120 @@
|
||||
package filex
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Zip 打包成zip文件 可以是目录或单个文件
|
||||
func Zip(srcFile string, destZip string) error {
|
||||
// 预防:旧文件无法覆盖
|
||||
os.RemoveAll(destZip)
|
||||
|
||||
//创建zip文件
|
||||
zipFile, err := os.Create(destZip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer zipFile.Close()
|
||||
|
||||
//打开zip文件
|
||||
archive := zip.NewWriter(zipFile)
|
||||
defer archive.Close()
|
||||
|
||||
//遍历目录
|
||||
filepath.Walk(srcFile, func(path string, info os.FileInfo, err error) error {
|
||||
//println(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
header.Name = strings.TrimPrefix(path, filepath.Dir(srcFile)+string(os.PathSeparator))
|
||||
println(header.Name)
|
||||
// header.Name = path
|
||||
if info.IsDir() {
|
||||
header.Name += "\\"
|
||||
} else {
|
||||
header.Method = zip.Deflate
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Unzip 解压 zip 文件到指定目录(兼容 GBK 编码的中文文件名)
|
||||
func Unzip(zipFile string, destDir string) error {
|
||||
zipReader, err := zip.OpenReader(zipFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer zipReader.Close()
|
||||
|
||||
for _, f := range zipReader.File {
|
||||
var decodeName string
|
||||
if f.Flags == 0 {
|
||||
//如果标致位是0 则是默认的本地编码 默认为gbk
|
||||
i := bytes.NewReader([]byte(f.Name))
|
||||
decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder())
|
||||
content, _ := io.ReadAll(decoder)
|
||||
decodeName = string(content)
|
||||
} else {
|
||||
//如果标志为是 1 << 11也就是 2048 则是utf-8编码
|
||||
decodeName = f.Name
|
||||
}
|
||||
fpath := filepath.Join(destDir, decodeName)
|
||||
if f.FileInfo().IsDir() {
|
||||
os.MkdirAll(fpath, os.ModePerm)
|
||||
} else {
|
||||
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
inFile, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer inFile.Close()
|
||||
|
||||
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
_, err = io.Copy(outFile, inFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user