dreamfactory_cmd/cmd/upgrade/tools/gz.go
2023-06-09 21:58:02 +08:00

128 lines
2.3 KiB
Go

package tools
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func UnGz(tarFile, dest string) error {
srcFile, err := os.Open(tarFile)
if err != nil {
return err
}
defer srcFile.Close()
gr, err := gzip.NewReader(srcFile)
if err != nil {
return err
}
defer gr.Close()
tr := tar.NewReader(gr)
for {
hdr, err := tr.Next()
if err != nil {
if err == io.EOF {
break
} else {
return err
}
}
filename := dest + hdr.Name
file, err := createFile(filename)
if err != nil {
return err
}
_, _ = io.Copy(file, tr)
}
return nil
}
func createFile(name string) (*os.File, error) {
err := os.MkdirAll(string([]rune(name)[0:strings.LastIndex(name, "/")]), 0755)
if err != nil {
return nil, err
}
return os.Create(name)
}
func UnGzip(tarName, xpath string) (err error) {
tarFile, err := os.Open(tarName)
if err != nil {
return err
}
defer func() {
err = tarFile.Close()
}()
if err := os.Mkdir(xpath, 0755); err != nil {
return err
}
absPath, err := filepath.Abs(xpath)
if err != nil {
return err
}
tr := tar.NewReader(tarFile)
if strings.HasSuffix(tarName, ".gz") || strings.HasSuffix(tarName, ".gzip") {
gz, err := gzip.NewReader(tarFile)
if err != nil {
return err
}
defer gz.Close()
tr = tar.NewReader(gz)
}
// untar each segment
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
// determine proper file path info
finfo := hdr.FileInfo()
fileName := hdr.Name
if filepath.IsAbs(fileName) {
fmt.Printf("removing / prefix from %s\n", fileName)
fileName, err = filepath.Rel("/", fileName)
if err != nil {
return err
}
}
absFileName := filepath.Join(absPath, fileName)
if finfo.Mode().IsDir() {
if err := os.MkdirAll(absFileName, 0755); err != nil {
return err
}
continue
}
// create new file with original file mode
file, err := os.OpenFile(absFileName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, finfo.Mode().Perm())
if err != nil {
return err
}
fmt.Printf("x %s\n", absFileName)
n, cpErr := io.Copy(file, tr)
if closeErr := file.Close(); closeErr != nil { // close file immediately
return err
}
if cpErr != nil {
return cpErr
}
if n != finfo.Size() {
return fmt.Errorf("unexpected bytes written: wrote %d, want %d", n, finfo.Size())
}
}
return nil
}