Go 如何打包与压缩文件
在Go语言中,打包与压缩文件的功能由标准库中的archive包和compress包提供。archive包提供了对结构化文件格式(如tar、zip)进行读写的功能,而compress包提供了各种压缩算法(如gzip、zlib、flate等)的支持。
1. 压缩文件
在Go语言中,压缩文件的操作非常简单。我们只需要导入compress/gzip包,使用如下代码即可对文件进行压缩:
import (
"compress/gzip"
"io"
"os"
)
func gzipFile(inputPath, outputPath string) error {
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
gzipWriter := gzip.NewWriter(outputFile)
defer gzipWriter.Close()
_, err = io.Copy(gzipWriter, inputFile)
return err
}
以上代码可以将inputPath所指定的文件压缩后存储到outputPath所指定的路径下。使用gzip.NewWriter创建压缩器,然后使用io.Copy将数据从inputFile中复制到gzipWriter中,实现压缩后写入文件。需要注意的是,io.Copy是一个阻塞操作,如果需要压缩大文件时,可以使用多个goroutine进行并行压缩。
2. 解压文件
与压缩文件类似,在Go语言中解压文件也很简单。我们只需要导入compress/gzip包,使用如下代码即可解压文件:
import (
"compress/gzip"
"io"
"os"
)
func ungzipFile(inputPath, outputPath string) error {
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
gzipReader, err := gzip.NewReader(inputFile)
if err != nil {
return err
}
defer gzipReader.Close()
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
_, err = io.Copy(outputFile, gzipReader)
return err
}
以上代码可以将inputPath所指定的文件解压后存储到outputPath所指定的路径下。使用gzip.NewReader创建解压器,然后使用io.Copy将解压后的数据从gzipReader中复制到outputFile中,实现解压后写入文件。同样需要注意的是,io.Copy是一个阻塞操作,如果需要解压大文件时,可以使用多个goroutine进行并行解压。
3. 打包文件
在Go语言中,打包文件的操作也非常简单。我们只需要导入archive/zip包,使用如下代码即可对文件进行打包:
import (
"archive/zip"
"io"
"os"
)
func zipFiles(inputPaths []string, outputPath string) error {
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
zipWriter := zip.NewWriter(outputFile)
defer zipWriter.Close()
for _, inputPath := range inputPaths {
inputFile, err := os.Open(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
fileInfo, err := inputFile.Stat()
if err != nil {
return err
}
header, err := zip.FileInfoHeader(fileInfo)
if err != nil {
return err
}
header.Name = inputPath
zipFileWriter, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
_, err = io.Copy(zipFileWriter, inputFile)
if err != nil {
return err
}
}
return nil
}
以上代码可以将inputPaths所指定的多个文件打包后存储到outputPath所指定的路径下。使用zip.NewWriter创建打包器,然后遍历inputPaths,逐个将文件打包写入。需要注意的是,打包文件时需要为每个被打包的文件创建一个新的Header,并指定文件名。然后使用zipWriter.CreateHeader创建对应的Writer,将文件数据写入即可。
4. 解包文件
与打包文件类似,在Go语言中解包文件也很简单。我们只需要导入archive/zip包,使用如下代码即可对文件进行解包:
import (
"archive/zip"
"io"
"os"
)
func unzipFiles(inputPath, outputPath string) error {
inputFile, err := zip.OpenReader(inputPath)
if err != nil {
return err
}
defer inputFile.Close()
for _, file := range inputFile.File {
fileReader, err := file.Open()
if err != nil {
return err
}
defer fileReader.Close()
filepath := filepath.Join(outputPath, file.Name)
if file.FileInfo().IsDir() {
os.MkdirAll(filepath, file.Mode())
} else {
outputFile, err := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
if err != nil {
return err
}
defer outputFile.Close()
_, err = io.Copy(outputFile, fileReader)
if err != nil {
return err
}
}
}
return nil
}
以上代码可以将inputPath所指定的打包文件解包后存储到outputPath所指定的路径下。使用zip.OpenReader创建解包器,然后遍历每个被打包的文件,逐个将文件解包后写入磁盘。需要注意的是,解包文件时需要根据FileInfo判断解包文件是否为目录。如果为目录,则使用os.MkdirAll创建对应的目录;否则,则使用os.OpenFile创建新的输出文件,并将解包后的数据写入。
总结
Go语言中,打包与压缩文件的功能由标准库中的archive包和compress包提供。使用这两个包能够轻松地实现对文件的打包与压缩操作。 值得一提的是,archive包和compress包中提供的接口非常简单易用,同时也提供了多种压缩算法的支持,能够满足不同场景的需要。