2014-11-09 16:24:19 +08:00
|
|
|
|
package archive
|
|
|
|
|
|
|
|
|
|
import (
|
2015-11-13 17:58:41 +08:00
|
|
|
|
"archive/zip"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"os"
|
|
|
|
|
"path"
|
2014-11-09 16:24:19 +08:00
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// main functions shows how to TarGz a directory/file and
|
|
|
|
|
// UnTarGz a file
|
|
|
|
|
// Gzip and tar from source directory or file to destination file
|
|
|
|
|
// you need check file exist before you call this function
|
|
|
|
|
|
|
|
|
|
func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
2014-11-09 16:24:19 +08:00
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
ok = false
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2015-11-13 17:58:41 +08:00
|
|
|
|
fw, err := os.Create(destFilePath)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
defer fw.Close()
|
|
|
|
|
|
|
|
|
|
// Tar writer
|
|
|
|
|
tw := zip.NewWriter(fw)
|
|
|
|
|
defer tw.Close()
|
|
|
|
|
|
|
|
|
|
// Check if it's a file or a directory
|
|
|
|
|
f, err := os.Open(srcDirPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
fi, err := f.Stat()
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
if fi.IsDir() {
|
|
|
|
|
// handle source directory
|
|
|
|
|
// fmt.Println("Cerating tar.gz from directory...")
|
|
|
|
|
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
|
|
|
|
} else {
|
|
|
|
|
// handle file directly
|
|
|
|
|
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
|
|
|
|
zipFile(srcDirPath, fi.Name(), tw, fi)
|
|
|
|
|
}
|
|
|
|
|
ok = true
|
|
|
|
|
return
|
2014-11-09 16:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deal with directories
|
|
|
|
|
// if find files, handle them with zipFile
|
|
|
|
|
// Every recurrence append the base path to the recPath
|
|
|
|
|
// recPath is the path inside of tar.gz
|
|
|
|
|
func zipDir(srcDirPath string, recPath string, tw *zip.Writer) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// Open source diretory
|
|
|
|
|
dir, err := os.Open(srcDirPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
defer dir.Close()
|
|
|
|
|
|
|
|
|
|
// Get file info slice
|
|
|
|
|
fis, err := dir.Readdir(0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
for _, fi := range fis {
|
|
|
|
|
// Append path
|
|
|
|
|
curPath := srcDirPath + "/" + fi.Name()
|
|
|
|
|
// Check it is directory or file
|
|
|
|
|
if fi.IsDir() {
|
|
|
|
|
// Directory
|
|
|
|
|
// (Directory won't add unitl all subfiles are added)
|
|
|
|
|
// fmt.Printf("Adding path...%s\n", curPath)
|
|
|
|
|
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
|
|
|
|
} else {
|
|
|
|
|
// File
|
|
|
|
|
// fmt.Printf("Adding file...%s\n", curPath)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
|
|
|
|
}
|
2014-11-09 16:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Deal with files
|
|
|
|
|
func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
if fi.IsDir() {
|
|
|
|
|
// fmt.Println("??")
|
|
|
|
|
// Create tar header
|
|
|
|
|
/*
|
|
|
|
|
fh, err := zip.FileInfoHeader(fi)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
fh.Name = recPath // + "/"
|
|
|
|
|
err = tw.WriteHeader(hdr)
|
|
|
|
|
tw.Create(recPath)
|
|
|
|
|
*/
|
|
|
|
|
} else {
|
|
|
|
|
// File reader
|
|
|
|
|
fr, err := os.Open(srcFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
defer fr.Close()
|
|
|
|
|
|
|
|
|
|
// Write hander
|
|
|
|
|
w, err2 := tw.Create(recPath)
|
|
|
|
|
if err2 != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
// Write file data
|
|
|
|
|
_, err = io.Copy(w, fr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-09 16:24:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ungzip and untar from source file to destination directory
|
|
|
|
|
// you need check file exist before you call this function
|
|
|
|
|
func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
|
|
|
|
ok = false
|
|
|
|
|
msg = ""
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
|
|
|
|
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
2014-11-09 16:24:19 +08:00
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
|
msg = fmt.Sprintf("%v", err)
|
|
|
|
|
ok = false
|
|
|
|
|
}
|
|
|
|
|
}()
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-11-09 16:24:19 +08:00
|
|
|
|
os.Mkdir(destDirPath, os.ModePerm)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
r, err := zip.OpenReader(srcFilePath)
|
2014-11-09 16:24:19 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
defer r.Close()
|
2014-11-09 16:24:19 +08:00
|
|
|
|
for _, f := range r.File {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
|
|
|
|
rc, err := f.Open()
|
|
|
|
|
if err != nil {
|
2014-11-09 16:24:19 +08:00
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-11-09 16:24:19 +08:00
|
|
|
|
// 把首文件夹去掉, 即j去掉, 分离出文件夹和文件名
|
|
|
|
|
paths := strings.Split(f.Name, "/")
|
|
|
|
|
prePath := ""
|
|
|
|
|
filename := ""
|
|
|
|
|
l := len(paths)
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// fmt.Println(l)
|
2014-11-09 16:24:19 +08:00
|
|
|
|
if l > 1 {
|
|
|
|
|
// 去掉第1个文件夹
|
|
|
|
|
if l == 2 {
|
|
|
|
|
filename = paths[1]
|
|
|
|
|
} else {
|
|
|
|
|
filename = paths[l-1]
|
|
|
|
|
prePath = strings.Join(paths[1:l-1], "/")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
filename = f.Name
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// fmt.Println(prePath)
|
|
|
|
|
|
2014-11-09 16:24:19 +08:00
|
|
|
|
// 相对于目标文件件下的路径
|
2015-11-13 17:58:41 +08:00
|
|
|
|
destPath := destDirPath + "/" + filename
|
2014-11-09 16:24:19 +08:00
|
|
|
|
if prePath != "" {
|
2015-11-13 17:58:41 +08:00
|
|
|
|
os.MkdirAll(destDirPath+"/"+prePath, os.ModePerm)
|
2014-11-09 16:24:19 +08:00
|
|
|
|
destPath = destDirPath + "/" + prePath + "/" + filename
|
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
// Write data to file
|
|
|
|
|
// fmt.Println(destPath)
|
|
|
|
|
fw, _ := os.Create(destPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
_, err = io.Copy(fw, rc)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2014-11-09 16:24:19 +08:00
|
|
|
|
}
|
2015-11-13 17:58:41 +08:00
|
|
|
|
|
2014-11-09 16:24:19 +08:00
|
|
|
|
ok = true
|
|
|
|
|
return
|
2015-11-13 17:58:41 +08:00
|
|
|
|
}
|