golang封装tar打包解包之二
导读:好久没上来这里写专栏了,发现上一篇有关tar打包解包还留着一个坑。这里补上。本文介绍下通过os/exec调用shell命令,直接调用系统的tar命令进行打包。方案二、通过调用系统的tar命令基本思路是先拼接tar打包和解包的命令,然后调用o...
好久没上来这里写专栏了,发现上一篇有关tar打包解包还留着一个坑。这里补上。
本文介绍下通过os/exec调用shell命令,直接调用系统的tar命令进行打包。
方案二、通过调用系统的tar命令
基本思路是先拼接tar打包和解包的命令,然后调用os/exec包的CommandContext方法执行shell命令。这里要求操作系统中需要有tar命令。
公共方法的定义
这里定义一个结构体,对日志的读取、shell脚本的执行做了封装。当然如果需要执行其他shell命令,直接给exec方法传入具体命令也是可以的。
type TgzLinuxPacker struct {
ctx context.Context // context上下文,监听上层的退出信号
cancel context.CancelFunc // context的取消函数
wg sync.WaitGroup
outputList []string // 命令的输出
}
func NewTgzLinuxPacker(ctx context.Context) *TgzLinuxPacker {
subCtx, cancel := context.WithCancel(ctx)
return &
TgzLinuxPacker{
ctx: subCtx,
cancel: cancel,
wg: sync.WaitGroup{
}
,
outputList: make([]string, 0),
}
}
// 从标准输出、错误输出读取内容
func (tlp *TgzLinuxPacker) readLog(stdReader io.Reader) {
defer tlp.wg.Done()
reader := bufio.NewReader(stdReader)
for {
select {
case -tlp.ctx.Done():
return
default:
readString, err := reader.ReadString('\n')
if err != nil || err == io.EOF {
return
}
line := strings.Trim(readString, "\n")
tlp.outputList = append(tlp.outputList, line)
}
}
}
// 命令执行的封装
func (tlp *TgzLinuxPacker) exec(cmdStr string) error {
// 方法退出时触发cancel方法的调用,通知readLog和shell子进程退出
defer tlp.cancel()
c := exec.CommandContext(tlp.ctx, "/bin/bash", "-c", cmdStr)
// get stdout stderr pipe
stdout, err := c.StdoutPipe()
if err != nil {
return err
}
stderr, err := c.StderrPipe()
if err != nil {
return err
}
// read stdout stderr
tlp.wg.Add(2)
go tlp.readLog(stdout)
go tlp.readLog(stderr)
// 开始执行
err = c.Start()
if err != nil {
return err
}
// 等待readLog退出
tlp.wg.Wait()
// 这里调用一次wait,获取shell进程的退出码
err = c.Wait()
if err != nil {
return errors.New(strings.Join(tlp.outputList, "\n") + err.Error())
}
if !c.ProcessState.Success() {
return errors.New("返回码:" + strconv.Itoa(c.ProcessState.ExitCode()) + "\n" + strings.Join(tlp.outputList, "\n"))
}
return nil
}
压缩打包
有了执行shell命令的方法后,我们要进行打包的工作,那就相当简单了,直接拼接命令行即可
func (tlp *TgzLinuxPacker) Pack(sourceFullPath string, tarFileName string) error {
// e.g: tar -zcf test.tar.gz -C /tmp/ test
cmdStr := "tar -zcf " + tarFileName + " -C " + filepath.Dir(sourceFullPath) + " " + filepath.Base(sourceFullPath)
return tlp.exec(cmdStr)
}
解压
同压缩打包,值需要拼接解压命令即可
func (tlp *TgzLinuxPacker) Unpack(tarFileName string, dstDir string) error {
// e.g: tar -zxf /tmp/test.tar.gz -C /tmp/
cmdStr := "tar -zxf " + tarFileName + " -C " + dstDir
return tlp.exec(cmdStr)
}
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: golang封装tar打包解包之二
本文地址: https://pptw.com/jishu/571818.html