TOC

Golang archive

标准库中的 archive 支持 tarzip 两种打包格式。

https://en.wikipedia.org/wiki/Tar_(computing)

最常用的 tar 包:

func createTarArchive(sourceDir, targetFile string) error {
    file, err := os.Create(targetFile)
    if err != nil {
        return err
    }
    defer file.Close()

    tarWriter := tar.NewWriter(file)
    defer tarWriter.Close()

    return filepath.Walk(sourceDir, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        header, err := tar.FileInfoHeader(info, info.Name())
        if err != nil {
            return err
        }

        if err := tarWriter.WriteHeader(header); err != nil {
            return err
        }

        if !info.IsDir() {
            file, err := os.Open(path)
            if err != nil {
                return err
            }
            defer file.Close()

            _, err = io.Copy(tarWriter, file)
            if err != nil {
                return err
            }
        }

        return nil
    })
}

func extractTarArchive(sourceFile, targetDir string) error {
    file, err := os.Open(sourceFile)
    if err != nil {
        return err
    }
    defer file.Close()

    tarReader := tar.NewReader(file)
    for {
        header, err := tarReader.Next()
        if err == io.EOF {
            break
        }
        if err != nil {
            return err
        }
        targetPath := filepath.Join(targetDir, header.Name)
        if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
            return err
        }
        if header.Typeflag == tar.TypeReg {
            file, err := os.Create(targetPath)
            if err != nil {
                return err
            }
            defer file.Close()
            _, err = io.Copy(file, tarReader)
            if err != nil {
                return err
            }
        }
    }

    return nil
}