go压缩和解压文件

发布时间 2023-03-22 21:09:33作者: 许伟强

压缩和解压文件

package main

import (
    "archive/tar"
    "compress/gzip"
    "fmt"
    "io"
    "os"
    "strings"
)

// Compress 压缩 使用gzip压缩成tar.gz
func Compress(files []*os.File, dest string) error {
    d, _ := os.Create(dest)
    defer d.Close()
    gw := gzip.NewWriter(d)
    defer gw.Close()
    tw := tar.NewWriter(gw)
    defer tw.Close()
    for _, file := range files {
        err := compress(file, "", tw)
        if err != nil {
            return err
        }
    }
    return nil
}

// compress tool of compress
func compress(file *os.File, prefix string, tw *tar.Writer) error {
    info, err := file.Stat()
    if err != nil {
        return err
    }
    if info.IsDir() {
        prefix = prefix + "/" + info.Name()
        fileInfos, err := file.Readdir(-1)
        if err != nil {
            return err
        }
        for _, fi := range fileInfos {
            f, err := os.Open(file.Name() + "/" + fi.Name())
            if err != nil {
                return err
            }
            err = compress(f, prefix, tw)
            if err != nil {
                return err
            }
        }
    } else {
        header, err := tar.FileInfoHeader(info, "")
        header.Name = prefix + "/" + header.Name
        if err != nil {
            return err
        }
        err = tw.WriteHeader(header)
        if err != nil {
            return err
        }
        _, err = io.Copy(tw, file)
        file.Close()
        if err != nil {
            return err
        }
    }
    return nil
}

// DeCompress 解压 tar.gz
func DeCompress(tarFile, dest string) error {
    srcFile, err := os.Open(tarFile)
    if err != nil {
        return err
    }
    defer srcFile.Close()
    gr, err := gzip.NewReader(srcFile)
    if err != nil {
        return err
    }
    defer gr.Close()
    tr := tar.NewReader(gr)
    for {
        hdr, err := tr.Next()
        if err != nil {
            if err == io.EOF {
                break
            } else {
                return err
            }
        }
        filename := dest + hdr.Name
        file, err := createFile(filename)
        if err != nil {
            return err
        }
        _, err = io.Copy(file, tr)
        if err != nil {
            return err
        }
    }
    return nil
}

// createFile create file
func createFile(name string) (*os.File, error) {
    err := os.MkdirAll(string([]rune(name)[0:strings.LastIndex(name, "/")]), 0o755)
    if err != nil {
        return nil, err
    }
    return os.Create(name)
}

// TraverseFolder file for each
func TraverseFolder(tempPath string) ([]*os.File, error) {
    files, err := os.ReadDir(tempPath)
    if err != nil {
        return nil, err
    }
    var myFile []*os.File
    for _, file := range files {
        tmpOsFile, err := os.Open(fmt.Sprintf("%s/%s", tempPath, file.Name()))
        if err != nil {
            return nil, err
        }
        myFile = append(myFile, tmpOsFile)
    }
    return myFile, nil
}

验证解压和压缩文件

package main

import (
    "os"
)

func main() {
    dstPath := "tmp.tar.gz"
    tempFileList, err := TraverseFolder("./temp")
    if err != nil {
        panic(err)
    }
    versionFile, err := os.Open("./version/version.yml")
    if err != nil {
        panic(err)
    }
    var zipFileList []*os.File
    zipFileList = append(zipFileList, tempFileList...)
    zipFileList = append(zipFileList, versionFile)
    Compress(zipFileList, dstPath)
    DeCompress(dstPath, "unCompress")
}