package main
import (
"archive/tar" "io" "io/ioutil" "log" "os" "path"
)
func main() {
//TarDynamicContent() //UnTar("D:/home/mytar.tar", "D:/home/mytar/") TarExistFile("D:/home/gif/111.gif")
}
func UnTar(srcTar string, dstDir string) {
// 清理路径字符串 dstDir = path.Clean(dstDir) + "/" // 打开要解包的文件 fr, er := os.Open(srcTar) if er != nil { log.Fatalln(er) } defer fr.Close() // 创建 tar.Reader,准备执行解包操作 tr := tar.NewReader(fr) // 遍历包中的文件 for hdr, er := tr.Next(); er != io.EOF; hdr, er = tr.Next() { if er != nil { log.Fatalln(er) continue } // 获取文件信息 fi := hdr.FileInfo() // 获取绝对路径 dstFullPath := dstDir + hdr.Name if hdr.Typeflag == tar.TypeDir { // 创建目录 os.MkdirAll(dstFullPath, fi.Mode().Perm()) // 设置目录权限 os.Chmod(dstFullPath, fi.Mode().Perm()) } else { // 创建文件所在的目录 os.MkdirAll(path.Dir(dstFullPath), os.ModePerm) // 将 tr 中的数据写入文件中 if er := unTarFile(dstFullPath, tr); er != nil { log.Fatalln(er) } // 设置文件权限 os.Chmod(dstFullPath, fi.Mode().Perm()) } }
}
// 因为要在 defer 中关闭文件,所以要单独创建一个函数
func unTarFile(dstFile string, tr *tar.Reader) error {
// 创建空文件,准备写入解包后的数据 fw, er := os.Create(dstFile) if er != nil { return er } defer fw.Close() // 写入解包后的数 _, er = io.Copy(fw, tr) if er != nil { return er } return nil
}
func TarExistFile(srcPath string) {
// 创建空的目标文件 fw, _ := os.Create("D:/home/mytar-file.tar") defer fw.Close() // 创建 tar.Writer,执行打包操作 tw := tar.NewWriter(fw) defer func() { tw.Flush() tw.Close() }() // 获取文件或目录信息 fi, _ := os.Stat(srcPath) // 获取要打包的文件或目录的所在位置(parent dir) 和 名称 parentDir, dirOrFileName := path.Split(path.Clean(srcPath)) // 开始打包 if fi.IsDir() { tarDir(parentDir, dirOrFileName, tw, fi) } else { tarFile(parentDir, dirOrFileName, tw, fi) }
}
// 因为要执行遍历操作,所以要单独创建一个函数
func tarDir(parentDir, dirName string, tw *tar.Writer, fi os.FileInfo) {
// 写入目录信息 if len(dirName) > 0 { hdr, _ := tar.FileInfoHeader(fi, "") hdr.Name = dirName tw.WriteHeader(hdr) } dirFull := parentDir + dirName + "/" // 获取 srcFull 下的文件或子目录列表 fis, _ := ioutil.ReadDir(dirFull) // 开始遍历 for _, nfi := range fis { if nfi.IsDir() { tarDir(parentDir, dirName+"/"+nfi.Name(), tw, nfi) } else { tarFile(parentDir, dirName+"/"+nfi.Name(), tw, nfi) } }
}
// 因为要在 defer 中关闭文件,所以要单独创建一个函数
func tarFile(fileDir, filename string, tw *tar.Writer, fi os.FileInfo) {
// 获取完整路径 filepath := fileDir + filename log.Println("file: ", filepath) // 写入文件信息 hdr, _ := tar.FileInfoHeader(fi, "") hdr.Name = filename tw.WriteHeader(hdr) fb, _ := ioutil.ReadFile(filepath) tw.Write(fb)
}
func TarDynamicContent() {
// 创建空的目标文件 fw, er := os.Create("D:/home/mytar.tar") if er != nil { log.Fatalln(er) } defer fw.Close() // 创建 tar.Writer,执行打包操作 tw := tar.NewWriter(fw) defer func() { tw.Flush() // 这里要判断 tw 是否关闭成功,如果关闭失败,则 .tar 文件可能不完整 if er := tw.Close(); er != nil { log.Fatalln(er) } }() //要打包的内容 var files = []struct { Name, Body string }{ {"readme.txt", "thie archive contains some text files"}, {"gopher.txt", "Gopher names:\nGeorge \nGeoffrey\nGonzo"}, {"todo.txt", "Get animal handling licence"}, } //写入tar for _, file := range files { hdr := &tar.Header{ Name: file.Name, Size: int64(len(file.Body)), } if err := tw.WriteHeader(hdr); err != nil { log.Fatalln(err) } if _, err := tw.Write([]byte(file.Body)); err != nil { log.Fatalln(err) } }
}
时间: 2024-10-12 20:57:27