Go语言通过archive/tar和archive/zip包实现归档文件处理,配合io和os包可完成文件打包与解包。1. tar打包使用tar.NewWriter将目录遍历写入tar文件,通过filepath.Walk获取文件信息并写入header和数据;解包时用tar.NewReader读取每个header,根据类型创建目录或文件并复制数据。2. zip打包使用zip.NewWriter,设置header的压缩方法为Deflate,逐个写入文件;解包通过zip.OpenReader读取文件列表,创建对应路径并复制内容。使用时需注意路径分隔符统一、权限设置、大文件流式处理、错误及时返回及压缩级别配置,确保跨平台兼容性和资源安全释放。

在Go语言中,处理归档文件(如tar和zip)是常见的需求,比如打包日志、分发配置或实现备份功能。Go标准库提供了 archive/tar 和 archive/zip 包,配合 io、os 等基础包可以实现完整的打包与解包功能。下面分别介绍 tar 和 zip 格式的打包与解包实现方式。
1. tar 打包(压缩目录或文件)
使用 archive/tar 包创建 tar 归档文件。tar 本身不压缩,只是将多个文件合并为一个。
示例:将指定目录打包为 .tar 文件
立即学习“go语言免费学习笔记(深入)”;
func tarDir(srcDir, tarFile string) error {
outFile, err := os.Create(tarFile)
if err != nil {
return err
}
defer outFile.Close()
tarWriter := tar.NewWriter(outFile)
defer tarWriter.Close()
return filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return err
}
// 调整 header 中的 Name 为相对路径
relPath, _ := filepath.Rel(srcDir, path)
header.Name = filepath.ToSlash(relPath)
if header.Name == "" {
return nil
}
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)
return err
}
return nil
})
}
2. tar 解包(提取归档文件)
读取 .tar 文件并逐个提取文件到目标目录。
func untar(tarFile, dest string) error {
file, err := os.Open(tarFile)
if err != nil {
return err
}
defer file.Close()
reader := tar.NewReader(file)
for {
header, err := reader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
targetPath := filepath.Join(dest, header.Name)
switch header.Typeflag {
case tar.TypeDir:
if _, err := os.Stat(targetPath); err != nil {
os.MkdirAll(targetPath, 0755)
}
case tar.TypeReg:
dir := filepath.Dir(targetPath)
os.MkdirAll(dir, 0755)
outFile, err := os.Create(targetPath)
if err != nil {
return err
}
_, err = io.Copy(outFile, reader)
outFile.Close()
if err != nil {
return err
}
}
}
return nil
}
1. zip 打包(压缩文件或目录)
zip 支持压缩,Go 的 archive/zip 包可直接创建压缩文件。
func zipDir(srcDir, zipFile string) error {
outFile, err := os.Create(zipFile)
if err != nil {
return err
}
defer outFile.Close()
zipWriter := zip.NewWriter(outFile)
defer zipWriter.Close()
return filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
relPath, _ := filepath.Rel(srcDir, path)
if relPath == "." {
return nil
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
header.Name = filepath.ToSlash(relPath)
if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate // 使用压缩
}
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
if !info.IsDir() {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
}
return nil
})
}
2. zip 解包(解压文件)
读取 zip 文件并提取内容。
func unzip(zipFile, dest string) error {
reader, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer reader.Close()
for _, file := range reader.File {
filePath := filepath.Join(dest, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(filePath, 0755)
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), 0755); err != nil {
return err
}
inFile, err := file.Open()
if err != nil {
return err
}
outFile, err := os.Create(filePath)
if err != nil {
inFile.Close()
return err
}
_, err = io.Copy(outFile, inFile)
outFile.Close()
inFile.Close()
if err != nil {
return err
}
}
return nil
}
实际使用中需要注意以下几点:
基本上就这些。Go 的 archive 包设计清晰,配合 io 流操作,实现归档功能不复杂但容易忽略路径和资源释放细节。
以上就是Golang archive打包解包 tar/zip实现的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号