archive/tar

<!-- lang: cpp -->
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)
	}
}

}

转载于:https://my.oschina.net/beloser/blog/321046

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值