golang代码可以tar 目录和文件的,并且tar包是以要打包的文件或者目录名字命名tar包,如果是打包目录,目录结构和里面的文件也可以递归打包
如下面示例代码tar.go中
sourceDir := "/root/test_tar/"
targetDir := "/root/test_untar/"
sourceTar := "/root/test_untar/test_tar.tar.gz"
targetUnTarDir := "/root/test_untar/"
打包:我将test_tar打包成test_tar.tar.gz保存在/root/test_untar/
解包:我将刚才打包的/root/test_untar/test_tar.tar.gz解包到/root/test_untar/
提示:目标目录不可以包含在源目录内,否则会造成递归打包
解压到保存目录必须是个目录
代码示例 tar.gopackage main
import (
"archive/tar"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func Tar(source, target string) error {
filename := filepath.Base(source)
target = filepath.Join(target, fmt.Sprintf("%s.tar.gz", filename))
tarfile, err := os.Create(target)
if err != nil {
return err
}
defer tarfile.Close()
tarball := tar.NewWriter(tarfile)
defer tarball.Close()
info, err := os.Stat(source)
if err != nil {
return nil
}
var baseDir string
if info.IsDir() {
baseDir = filepath.Base(source)
}
return filepath.Walk(source,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
if baseDir != "" {
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
}
if err := tarball.WriteHeader(header); err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(tarball, file)
return err
})
}
func UnTar(tarball, target string) error {
reader, err := os.Open(tarball)
if err != nil {
return err
}
defer reader.Close()
tarReader := tar.NewReader(reader)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
} else if err != nil {
return err
}
path := filepath.Join(target, header.Name)
info := header.FileInfo()
if info.IsDir() {
if err = os.MkdirAll(path, info.Mode()); err != nil {
return err
}
continue
}
file, err:= os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, info.Mode())
if err != nil {
return err
}
defer file.Close()
_, err =io.Copy(file, tarReader)
if err != nil {
return err
}
}
return nil
}
func main() {
sourceDir := "/root/test_tar/"
targetDir := "/root/test_untar/"
if err := Tar(sourceDir, targetDir); err != nil {
fmt.Printf("tar failed %s\n", err.Error())
}
sourceTar := "/root/test_untar/test_tar.tar.gz"
targetUnTarDir := "/root/test_untar/"
if err := UnTar(sourceTar,targetUnTarDir); err != nil {
fmt.Printf("Untar failed %s\n",err.Error())
}
}
程序测验
程序执行前:
执行go run tar.go之后