package compression import ( "archive/tar" "compress/gzip" "io" "os" "path" "path/filepath" "strings" ) type TGZHandler struct { } func NewTGZHandler() *TGZHandler { return &TGZHandler{} } // UNTarGZ 解压tar.gz文件到指定目录,包含顶层文件夹 func (z *TGZHandler) UNTarGZ(src, dst string) error { archive, err := os.Open(src) if err != nil { return err } defer func(archive *os.File) { err := archive.Close() if err != nil { return } }(archive) gr, err := gzip.NewReader(archive) if err != nil { return err } defer func(gr *gzip.Reader) { err := gr.Close() if err != nil { return } }(gr) tr := tar.NewReader(gr) for { f, err := tr.Next() if err == io.EOF { break } if err != nil { return err } filePath := path.Join(dst, f.Name) if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } if f.FileInfo().IsDir() { err := os.MkdirAll(filePath, os.ModePerm) if err != nil { return err } continue } else { fileName := path.Join(dst, f.Name) fw, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(f.Mode)) defer func(fw *os.File) { err := fw.Close() if err != nil { return } }(fw) if err != nil { return err } if _, err := io.Copy(fw, tr); err != nil { return err } } } return nil } // UNTarGZTo 解压tar.gz文件到指定目录,不包含顶层文件夹,只是将文件解压到指定目录 func (z *TGZHandler) UNTarGZTo(src, dst string) error { archive, err := os.Open(src) if err != nil { return err } defer func(archive *os.File) { err := archive.Close() if err != nil { return } }(archive) gr, err := gzip.NewReader(archive) if err != nil { return err } defer func(gr *gzip.Reader) { err := gr.Close() if err != nil { return } }(gr) tr := tar.NewReader(gr) for { f, err := tr.Next() if err == io.EOF { break } if err != nil { return err } filePath := path.Join(dst, f.Name) if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { return err } if f.FileInfo().IsDir() { err := os.MkdirAll(filePath, os.ModePerm) if err != nil { return err } continue } else { splitPath := strings.Split(f.Name, string(os.PathSeparator)) targetPath := strings.Join(splitPath[1:], string(os.PathSeparator)) filePath := filepath.Join(dst, targetPath) fw, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(f.Mode)) defer func(fw *os.File) { err := fw.Close() if err != nil { return } }(fw) if err != nil { return err } if _, err := io.Copy(fw, tr); err != nil { return err } } } return nil }