package gzip
import (
"compress/gzip"
"errors"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
"time"
"utils"
)
func fileToDecompress(gzfile, file string) string {
if file == "" {
file = gzfile
} else {
dir, fileName := filepath.Split(file)
if dir != "" {
err := os.MkdirAll(dir, 0755)
if err != nil {
log.Println(err)
return ""
}
}
if fileName == "" {
_, fileName = filepath.Split(gzfile)
}
file = filepath.Join(dir, fileName)
}
return strings.TrimSuffix(file, ".gz")
}
func fileToCompress(file, gzfile string) string {
if gzfile == "" {
gzfile = file
} else {
dir, fileName := filepath.Split(gzfile)
if dir != "" {
err := os.MkdirAll(dir, 0755)
if err != nil {
log.Println(err)
return ""
}
}
if fileName == "" {
_, fileName = filepath.Split(file)
}
gzfile = filepath.Join(dir, fileName)
}
if strings.ToLower(filepath.Ext(gzfile)) != ".gz" {
return gzfile + ".gz"
} else {
return gzfile
}
}
//压缩文件
//file 待压缩的文件 如 path/pkg.tar
//gzfile 压缩后的文件 如 path/pkg.tar.gz OR path/ OR 为空
func Compress(file, gzfile string) error {
if !utils.FileExists(file) {
return errors.New(`File "` + file + `" not exist.`)
}
gzfile = fileToCompress(file, gzfile)
if gzfile == "" {
return errors.New(`Can not determine file name to save.`)
}
gzfile = utils.UNCPath(gzfile)
file = utils.UNCPath(file)
in, err := os.Open(file)
defer in.Close()
if err != nil {
log.Println(err)
return err
}
out, err := os.Create(gzfile)
defer out.Close()
if err != nil {
log.Println(err)
return err
}
//zw, err := gzip.NewWriterLevel(out, gzip.DefaultCompression)
zw, err := gzip.NewWriterLevel(out, gzip.BestCompression)
if err != nil {
log.Println(err)
return err
}
// Setting the Header fields is optional.
zw.Name = filepath.Base(file)
zw.Comment = "NONE"
zw.ModTime = time.Now() //time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
//10M per read
var buffer []byte = make([]byte, 10*1024*1024)
for {
size, err := in.Read(buffer)
if err != nil {
if size == 0 && err == io.EOF {
break
} else {
log.Println(err)
return err
}
}
buffer = buffer[0:size]
_, err = zw.Write(buffer)
if err != nil {
log.Println(err)
return err
}
}
if err := zw.Close(); err != nil {
log.Println(err)
return err
}
return nil
}
//解压缩文件
//gzfile 待解压缩的文件 如 path/pkg.tar.gz
//file 解压缩后的文件 如 path/pkg.tar OR path/ OR 为空
func Decompress(gzfile, file string) error {
if !utils.FileExists(gzfile) {
return errors.New(`File "` + gzfile + `" not exist.`)
}
if strings.ToLower(filepath.Ext(gzfile)) != ".gz" {
return errors.New(`"` + gzfile + `" is not gzip file.`)
}
file = fileToDecompress(gzfile, file)
if gzfile == "" {
return errors.New(`Can not determine file name to save.`)
}
file = utils.UNCPath(file)
gzfile = utils.UNCPath(gzfile)
in, err := os.Open(gzfile)
if err != nil {
log.Println(err)
return err
}
zr, err := gzip.NewReader(in)
if err != nil {
log.Println(err)
return err
}
fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
out, err := os.Create(file)
if err != nil {
log.Println(err)
return err
}
if _, err := io.Copy(out, zr); err != nil {
log.Println(err)
return err
}
if err := zr.Close(); err != nil {
log.Println(err)
return err
}
return nil
}