golang 用tar打包文件或文件夾

打包文件用到了tar包,其中tar包的用法能夠參考API golang

golang提供了個函數用來遍歷文件夾 filepath.Walk函數

函數具體描述以下:ui

func Walk(root string, walkFn WalkFunc) error  root是用遍歷的文件夾spa

type WalkFuncorm

type WalkFunc func(path string, info os.FileInfo, err error) error path參數是返回遍歷的文件路徑和文件信息blog

在使用中如代碼中藍色部分,經過該方法呢,咱們能夠對文件和文件夾的操做更加熟悉,其中用到了get

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)
        }
    })
}
相關文章
相關標籤/搜索