Go语言通过archive/zip、archive/tar和compress/gzip包实现多格式文件压缩解压,支持zip和tar.gz的创建与解压,并可封装统一接口根据扩展名自动选择处理方式。
Go语言
标准库
对
文件压缩
操作提供了良好的支持,常见的
、
和
格式都可以通过内置包轻松实现。下面以实际代码示例说明如何在Golang中进行多格式的文件压缩与解压操作。
zip 文件的压缩与解压
压缩多个文件到 zip
使用
包可以将多个文件打包成一个 zip 压缩包。
func CompressToZip(files []string, dest string) error {
outFile, err := os.Create(dest)
if err != nil {
return err
}
defer outFile.Close()
zipWriter := zip.NewWriter(outFile)
defer zipWriter.Close()
for _, file := range files {
if err := addFileToZip(zipWriter, file); err != nil {
return err
}
}
return nil
}
func addFileToZip(zipWriter *zip.Writer, filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
header.Name = filepath.Base(filename)
header.Method = zip.Deflate
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(writer, file)
return err
}
解压 zip 文件
立即学习
“
go语言免费学习笔记(深入)
”;
func DecompressZip(zipPath, destDir string) error {
reader, err := zip.OpenReader(zipPath)
if err != nil {
return err
}
defer reader.Close()
for _, file := range reader.File {
filePath := filepath.Join(destDir, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(filePath, os.ModePerm)
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); 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)
inFile.Close()
outFile.Close()
if err != nil {
return err
}
}
return nil
}
tar + gzip 复合格式处理
tar 本身不压缩,通常结合 gzip 使用(即 .tar.gz)。Go 中需先用
打包,再用
压缩。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
创建 tar.gz 文件
func CompressToTarGz(sourceFiles []string, dest string) error {
outFile, err := os.Create(dest)
if err != nil {
return err
}
defer outFile.Close()
gzipWriter := gzip.NewWriter(outFile)
defer gzipWriter.Close()
tarWriter := tar.NewWriter(gzipWriter)
defer tarWriter.Close()
for _, file := range sourceFiles {
err := addFileToTar(tarWriter, file)
if err != nil {
return err
}
}
return nil
}
func addFileToTar(tarWriter *tar.Writer, filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
info, err := file.Stat()
if err != nil {
return err
}
header, err := tar.FileInfoHeader(info, "")
if err != nil {
return err
}
header.Name = filepath.Base(filename)
if err := tarWriter.WriteHeader(header); err != nil {
return err
}
_, err = io.Copy(tarWriter, file)
return err
}
解压 tar.gz 文件
func DecompressTarGz(tarGzPath, destDir string) error {
file, err := os.Open(tarGzPath)
if err != nil {
return err
}
defer file.Close()
gzipReader, err := gzip.NewReader(file)
if err != nil {
return err
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
targetPath := filepath.Join(destDir, header.Name)switchheader.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(targetPath, 0755); err != nil {
return err
}
case tar.TypeReg:
if err := os.MkdirAll(filepath.Dir(targetPath), 0755); err != nil {
return err
}
out, err := os.Create(targetPath)
if err != nil {
return err
}
_, err = io.Copy(out, tarReader)
out.Close()
if err != nil {
return err
}
}
}
return nil
}
统一接口支持多格式
为了方便调用,可以封装一个通用函数根据扩展名自动选择压缩方式。
func CompressFiles(format string, sources []string, dest string) error {
switch format {
case "zip":
return CompressToZip(sources, dest)
case "tar.gz":
return CompressToTarGz(sources, dest)
default:
return fmt.Errorf("不支持的格式: %s", format)
}
}
func DecompressArchive(archivePath, destDir string) error {
ext := filepath.Ext(archivePath)
if ext == ".zip" {
return DecompressZip(archivePath, destDir)
} else if ext == ".gz" {
// 判断是否为 .tar.gz
if strings.HasSuffix(archivePath, ".tar.gz") {
return DecompressTarGz(archivePath, destDir)
}
return fmt.Errorf("仅支持 .tar.gz 格式的 gzip 文件")
} else {
return fmt.Errorf("无法识别的压缩格式")
}
}
基本上就这些。通过组合使用
、
和
,Golang 能够灵活处理主流压缩格式。注意路径处理、目录创建和资源释放,就能写出稳定可靠的压缩工具。
ziptargziparchive/ziptargziparchive/ziparchive/tarcompress/gzip