zoukankan      html  css  js  c++  java
  • golang 用tar打包文件或文件夹

    打包文件用到了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) error

    strings.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)
            }
        })
    }

      

  • 相关阅读:
    Kafka系列之-Kafka入门
    2018个人年终总结
    javascript 模块化学习:Class打包出来无法实例化问题
    [SqlServer] Error: 15023
    [Auto Testing] 工具准备:Selenium 与 ChromeDriver
    [Python] 模拟登录网站(。。为了之后操作数据。。)
    [Angular 6] 初学angular,环境全部最新,[ ng serve ] 不能启动,卡在 95% 不动 => 解决方案
    [nuget]VS中包管理器打开后找不到其它工程的问题
    当需要给<span>标签设宽度
    关于近期打算
  • 原文地址:https://www.cnblogs.com/jfliuyun/p/6932426.html
Copyright © 2011-2022 走看看