go tar 打包目录和单个文件

2 篇文章 0 订阅
package main

import (
	"archive/tar"
	"bytes"
	"io"
	"fmt"
	"io/ioutil"
	"log"
	"reflect"
	"os"
	"time"
)

// 文件类型
const (
	TypeReg           = tar.TypeReg           // 普通文件
	TypeLink          = tar.TypeLink          // 硬链接
	TypeSymlink       = tar.TypeSymlink       // 符号链接
	TypeChar          = tar.TypeChar          // 字符节点
	TypeBlock         = tar.TypeBlock         // 块节点
	TypeDir           = tar.TypeDir           // 目录
	TypeFifo          = tar.TypeFifo          // 先进先出队列节点
	TypeCont          = tar.TypeCont          // 保留位
	TypeXHeader       = tar.TypeXHeader       // 扩展头
	TypeXGlobalHeader = tar.TypeXGlobalHeader // 全局扩展头
	TypeGNULongName   = tar.TypeGNULongName   // 下一个文件记录有个长名字
	TypeGNULongLink   = tar.TypeGNULongLink   // 下一个文件记录指向一个具有长名字的文件
	TypeGNUSparse     = tar.TypeGNUSparse     // 稀疏文件
)

// 实现了tar格式压缩文件的存取
func main() {
	// 被打包的包名
	tarFilePathName := "test.tar"
	// 需要打包的文件 或者目录
	//tarFileReadName := "网页操作"
	tarFileReadName := "a.txt"
	// tar打包
	tarCompresss(tarFilePathName,tarFileReadName)

}

// tar 打包
func tarCompresss(tarFilePathName string,tarFileReadName string)  {

	// 实例化一个结构体切片
	var files []struct{ Name string; Body string }
	//files := []struct {Name string;Body string}{}

	// 定义一个结构体用于存放文本文件信息
	type filess struct {Name,Body string}

	//声明buffer
	var buf bytes.Buffer
	// 初始化writer
	var tw = tar.NewWriter(&buf)

	// 判断被打包的文件是文件夹还是文本文件
	fi, e := os.Stat(tarFileReadName)
	if e != nil {
		fmt.Println("文件不存在")
	}
	if fi.IsDir() {
		fmt.Println("是目录")
		// 循环遍历目录中所有的文件
		files = listFiles(tarFileReadName)

	} else {
		fmt.Println("是文本文件")
		files = listFile(tarFileReadName)
	}

	for _, file := range files {
		// 打开文件并获取信息
		f, err := os.Open(file.Name)
		if err != nil {
			fmt.Println(err)
		}
		// 获取文件信息
		fii,_ := os.Stat(file.Name)

		// 根据结构体的内容实例化一个header
		hdr := &tar.Header{
			Name:       file.Name,             // 记录头域的文件名
			Mode:       0666,                  // 权限和模式位
			Uid:        0,                     // 所有者的用户ID
			Gid:        0,                     // 所有者的组ID
			Size:       fii.Size(), 			// 字节数(长度)
			ModTime:    time.Now(),            // 修改时间
			Typeflag:   TypeReg,               // 文件类型
			Linkname:   "",                    // 链接的目标名
			Uname:      "",                    // 所有者的用户名
			Gname:      "",                    // 所有者的组名
			Devmajor:   0,                     // 字符设备或块设备的major number
			Devminor:   0,                     // 字符设备或块设备的minor number
			AccessTime: time.Now(),            // 访问时间
			ChangeTime: time.Now(),            // 状态改变时间
		}

		// writer写入header
		if err := tw.WriteHeader(hdr); err != nil {
			log.Fatal(err)
		}

		var buff [2048]byte
		for {
			n, err := f.Read(buff[:])
			tw.Write(buff[:n])
			fmt.Println(reflect.TypeOf(buff[:n]))
			if err != nil {
				if err == io.EOF {
					break
				}
				fmt.Println(err)
			}
		}
	}

	// 关闭writer
	if err := tw.Close(); err != nil {
		log.Fatal(err)
	}

	// 自动生成并写入文件
	if err := ioutil.WriteFile(tarFilePathName, buf.Bytes(), os.ModePerm); err != nil {
		log.Fatal(err)
	}
}


// 循环遍历目录中所有的文件
func listFiles(dirName string) []struct{ Name string; Body string } {
	// 实例化一个结构体切片
	var files = []struct {
		Name, Body string
	}{ }

	type filess struct {
		Name,Body string
	}

	var listDirFiles func(dirName string)
	listDirFiles = func(dirName string) {
		fileInfos, err := ioutil.ReadDir(dirName)
		if err != nil {
			log.Fatal(err)
		}
		for _, fi := range fileInfos {
			filename := dirName + "/" + fi.Name()
			if fi.IsDir() {
				//递归调用方法
				listDirFiles(filename)
			} else {
				//fmt.Printf("%s\n", filename)
				//fmt.Println(reflect.TypeOf(filename))
				files = append(files,filess{filename,""})
			}
		}
	}
	listDirFiles(dirName)
	fmt.Println(reflect.TypeOf(files))
	return files
}

// 单个文件处理
func listFile(onlyFileName string) []struct{ Name string; Body string } {
	//var order []string
	// 实例化一个结构体切片
	var files = []struct {
		Name, Body string
	}{ }

	type filess struct {
		Name,Body string
	}

	var fileName func(onlyFileName string)
	fileName = func(onlyFileName string) {
		files = append(files,filess{onlyFileName,""})
	}
	fileName(onlyFileName)
	fmt.Println(reflect.TypeOf(files))
	return files
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值