打包文件用到了tar包,其中tar包的用法可以参考API

golang提供了个函数用来遍历文件夹 filepath.Walk

函数具体描述如下:

func Walk(root string, walkFn WalkFunc) error  root是用遍历的文件夹

type WalkFunc

type WalkFunc func(path string, info os.FileInfo, err error) error path参数是返回遍历的文件路径和文件信息

在使用中如代码中蓝色部分,通过该方法呢,我们可以对文件和文件夹的操作更加熟悉,其中用到了

os.Create 用来创建文件,返回文件信息和错误信息  func Create(name string) (file *File, err error)
os.Remove 用来删除文件,返回错误信息  func Remove(name string) error
os.Stat   用来返回文件具体信息,返回文件信息和错误信息   func (f *File) Stat() (fi FileInfo, err error)
os.Open   用来打开文件,返回文件信息和错误信息    func Open(name string) (file *File, err error)
io.Copy   复职文件信息到Writer 

func Copy(dst Writer, src Reader) (written int64, err error)func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
os.Mkdir 用来创建文件夹,返回错误信息  func Mkdir(name string, perm FileMode) errorstrings.TrimPrefix(targetpath, directory) 这个方法获取具体的文件路径相对目标文件夹的相对路径,也是在tar包中创建文件夹的相对路径
package main

import (
    "archive/tar"
    "fmt"
    "io"
    "os"
    "path/filepath"
    "strings"
)

/***生成***/

func createTar(filesource, filetarget string, deleteIfExist bool) error {
    //create tar file with targetfile name
    tarfile, err := os.Create(filetarget)

    if err != nil {
        // if file is exist then delete file
        if err == os.ErrExist {
            if err := os.Remove(filetarget); err != nil {
                fmt.Println(err)
                return err
            }
        } else {
            fmt.Println(err)
            return err
        }
    }
    defer tarfile.Close()

    tarwriter := tar.NewWriter(tarfile)

    sfileInfo, err := os.Stat(filesource)
    if err != nil {
        fmt.Println(err)
        return err
    }

    if !sfileInfo.IsDir() {
        return tarFile(filetarget, filesource, sfileInfo, tarwriter)

    } else {
        return tarFolder(filesource, tarwriter)
    }
    return nil
}

func tarFile(directory string, filesource string, sfileInfo os.FileInfo, tarwriter *tar.Writer) error {

    sfile, err := os.Open(filesource)

    if err != nil {
        panic(err)
        return err
    }
    defer sfile.Close()

    header, err := tar.FileInfoHeader(sfileInfo, "")
    if err != nil {
        fmt.Println(err)
        return err
    }
    header.Name = directory
    err = tarwriter.WriteHeader(header)
    if err != nil {
        fmt.Println(err)
        return err
    }
    //  can use buffer to copy the file to tar writer
    //    buf := make([]byte,15)
    //    if _, err = io.CopyBuffer(tarwriter, sfile, buf); err != nil {
    //        panic(err)
    //        return err
    //    }
    if _, err = io.Copy(tarwriter, sfile); err != nil {
        fmt.Println(err)
        panic(err)
        return err
    }
    return nil
}
func tarFolder(directory string, tarwriter *tar.Writer) error {

    var baseFolder string = filepath.Base(directory)
    //fmt.Println(baseFolder)
    return filepath.Walk(directory, func(targetpath string, file os.FileInfo, err error) error {
        //read the file failure
        if file == nil {
            panic(err)
            return err
        }
        if file.IsDir() {
            // information of file or folder
            header, err := tar.FileInfoHeader(file, "")
            if err != nil {
                return err
            }
            header.Name = filepath.Join(baseFolder, strings.TrimPrefix(targetpath, directory))
            fmt.Println(hdr.Name)
            if err = tarwriter.WriteHeader(header); err != nil {
                return err
            }
            os.Mkdir(strings.TrimPrefix(baseFolder, file.Name()), os.ModeDir)

            return nil

        } else {
            //baseFolder is the tar file path
            var fileFolder = filepath.Join(baseFolder, strings.TrimPrefix(targetpath, directory))
            return tarFile(fileFolder, targetpath, file, tarwriter)
        }
    })
}

  

golang 用tar打包文件或文件夹的更多相关文章

  1. linux中tar 打包指定路径文件

    linux中tar打包指定路径文件www.111cn.net 编辑:yahoo 来源:转载在linux系统中打包与解压文件我都可以使用tar命令来解决,只要使用不同的参数就可以实现不同的需要了,下面来 ...

  2. tar打包过滤某个文件及文件夹

    ip=ip add|grep eth0|grep -i inet|awk '{print $2}'|cut -d '/' -f 1 cd /data tar -zvcf `echo $ip`_`dat ...

  3. tar打包排除某个文件夹

    tar -zcvf package.tar.gz --exclude package/logs --exclude package/runtime ./package 使用exclude关键字设置需要 ...

  4. tar 打包当前目录下文件但不包括该录

    今天想打包一些文件,但是不想把该目录打包进去 比如我想把test目录下文件打个包,安装正常的命令来 tar zcf test.tar.gz test 这样肯定会把test目录也打进去,解压后肯定是te ...

  5. tar打包如何不打包某一个文件夹(排除某些文件夹)

    tar打包如何不打包某一个文件夹(排除某些文件夹) 问题描述: 最近想备份一下Tomcat运行的的功能文件,以防特殊情况的发生.但是在实际操作的过程中发现,可能是由于Unix/Linux版本太老的原因 ...

  6. linux下打包文件或文件夹

    转自:    在linux下如何将文件夹打包                 http://blog.csdn.net/cynhafa/article/details/7303338 linux zi ...

  7. tar 打包处理文件

    基本格式:tar [Options] file_archive //注意tar的第一参数必须为命令选项,即不能直接接待处理文件 Option是由三部分组成,分别是操作类型(创建,查看,解压),压缩处理 ...

  8. 使用Java API进行tar.gz文件及文件夹压缩解压缩

    在java(JDK)中我们可以使用ZipOutputStream去创建zip压缩文件,(参考我之前写的文章 使用java API进行zip递归压缩文件夹以及解压 ),也可以使用GZIPOutputSt ...

  9. Linux tar (打包.压缩.解压缩)命令说明 | tar如何解压文件到指定的目录?

    打包举例:将 /usr/local/src/zlib-1.2.5目录下的文件打包成 zlib-1.2.5.tar.gz cd /usr/local/src tar -czvf ./zlib-1.2.5 ...

随机推荐

  1. oracle 恢复数据到某个时间点

    delete from tablename;insert into tablename select * from tablename as of timestamp to_timestamp('20 ...

  2. Linux用户管理的复习时间

    所谓三天不练手生,你还记得关于Linux用户管理的所有知识吗?现在就来跟我一起复习一下吧! 1.常用配置文件 用户信息文件: /etc/password 密码文件: /etc/shadow 用户组文件 ...

  3. Python笔记·第一章—— Python基础(一)

    一.Python的简介 1.Python的由来与版本 1.1 python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文 ...

  4. ExtJs 带参数的MVC

    题记:研究使用ext两个星期了,从痛苦中逐渐走向明朗. 展示列表的子列表的数据时需要将当前的数据传给下一个mvc. 比如用户列表,点击一个用户查看该用户的日志列表. 首先是controller,放一个 ...

  5. 7、创建ROS msg和srv

    一.msg和srv介绍 msg: msg文件使用简单的文本格式声明一个ROS message的各个域. 仅须要创建一个msg文件,就能够使用它来生成不同语言的message定义代码. srv:srv文 ...

  6. SSM学习(一)搭建基础框架

    不知不自觉,工作也两年多了,由于公司一直用的是ssh框架,所以所学也一直是ssh.直到有一天,服务器被攻击,tomcat目录下总有莫名其妙的一些文件,这些文件通过远程ftp下载了一些病毒和木马,服务器 ...

  7. 关于scrapy的piplines

    1.进入setting中把ITEM_piplines文件注销去掉 2.在piplines中写好代码 # -*- coding: utf- -*- # Define your item pipeline ...

  8. jQuery:deferred [转]

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  9. Java并发编程有多难?这几个核心技术你掌握了吗?

    本文主要内容索引 1.Java线程 2.线程模型 3.Java线程池 4.Future(各种Future) 5.Fork/Join框架 6.volatile 7.CAS(原子操作) 8.AQS(并发同 ...

  10. Asp.Net Web API(六)

    Asp.Net Web API不可以需要IIS.可以自己在主机上承载一个Web API 创建WebAPI.Server项目 创建一个控制器项目的服务端 在Nuget中添加Microsoft.AspNe ...