原文地址:http://www.niu12.com/article/36
github地址:https://github.com/ZQCard/go_api_practice
// tar包實現了文件的打包功能,可以將多個文件或者目錄存儲到單一的.tar壓縮文件中
// tar本身不具有壓縮功能,只能打包文件或目錄
package main
import (
"archive/tar"
"fmt"
"io"
"os"
)
func main() {
// 普通文件
unTarFileName := "archive/tar/example/tar_example.txt"
// 壓縮文件
tarFileName := "archive/tar/example/tar_example.tar"
// 將普通文件生成壓縮文件
res := Tar(unTarFileName, tarFileName)
switch res.(type) {
case error:
fmt.Println("打包失敗:",res)
case bool:
fmt.Println("打包成功")
}
// 將壓縮文件解壓
tarFileName2 := "archive/tar/example/untar_example.tar"
unTarFilePath := "archive/tar/example/untar_example/"
res2 := UnTar(tarFileName2, unTarFilePath)
switch res2.(type) {
case error:
fmt.Println("解壓失敗:",res)
case bool:
fmt.Println("解壓成功")
}
}
func Tar(unTarFileName string, tarFileName string) interface{} {
// 打開源文件
sourceFile, err := os.Open(unTarFileName)
defer sourceFile.Close()
if err != nil {
return err
}
/* 向 tar 文件中寫入數據是通過 tar.Writer 完成的,所以首先要創建 tar.Writer,
可以通過 tar.NewWriter 方法來創建它,該方法要求提供一個 os.Writer 對象,
以便將打包后的數據寫入該對象中。
可以先創建一個文件,然后將該文件提供給 tar.NewWriter 使用。
*/
// 創建文件用於儲存打包后的數據
destinationFile, err := os.Create(tarFileName)
if err != nil {
return err
}
defer destinationFile.Close()
/* 創建tar.Writer對象.此時,我們就擁有了一個 tar.Writer 對象 tw,可以用它來打包文件了。
這里要注意一點,使用完 tw 后,一定要執行 tw.Close() 操作,
因為 tar.Writer 使用了緩存,tw.Close() 會將緩存中的數據寫入到文件中,
同時 tw.Close() 還會向 .tar 文件的最后寫入結束信息,如果不關閉 tw 而直接退出程序,
那么將導致 .tar 文件不完整。
存儲在 .tar 文件中的每個文件都由兩部分組成:文件頭信息和文件內容,
所以向 .tar 文件中寫入每個文件都要分兩步:
第一步寫入文件信息,第二步寫入文件數據。
對於目錄來說,由於沒有內容可寫,所以只需要寫入目錄信息即可。
*/
tw := tar.NewWriter(destinationFile)
defer tw.Close()
// 獲取源文件信息
sourceFileInfo, err := os.Stat(unTarFileName)
if err != nil {
return err
}
// 根據 os.FileInfo創建tar.Header信息頭
hdr, err := tar.FileInfoHeader(sourceFileInfo, "")
// 第一步寫入頭文件信息,通過tw.WriteHeader方法將hdr寫入.tar文件中
if err := tw.WriteHeader(hdr); err != nil {
return err
}
// 第二部,寫入數據
_, err = io.Copy(tw, sourceFile)
if err != nil {
return err
}
return true
}
func UnTar(tarFileName string, unTarFilePath string) interface{} {
// 將壓縮文件生成普通文件
// 解包的方法,從 .tar 文件中讀出數據是通過 tar.Reader 完成的,
// 所以首先要創建 tar.Reader,可以通過 tar.NewReader 方法來創建它.
// 該方法要求提供一個 os.Reader 對象,
// 以便從該對象中讀出數據。可以先打開一個 .tar 文件,
// 然后將該文件提供給 tar.NewReader 使用。
// 這樣就可以將 .tar 文件中的數據讀出來了:
tarFile, err := os.Open(tarFileName)
if err != nil {
return err
}
defer tarFile.Close()
// 創建tar.Reader 准備進行解包
tr := tar.NewReader(tarFile)
// 重新生成文件夾
path,err := os.Stat(unTarFilePath)
if path != nil{
os.RemoveAll(unTarFilePath)
}
os.Mkdir(unTarFilePath, os.ModePerm)
// 遍歷包中的文件
// 遍歷壓縮包中的文件
for{
hdr, err := tr.Next()
if err == io.EOF {
// 讀取到文件目錄,跳出循環
break
}
if err != nil {
return err
}
fileName := unTarFilePath + hdr.Name
_,err = os.Create(fileName)
if err != nil {
return err
}
fw, err := os.OpenFile(fileName, os.O_CREATE | os.O_WRONLY, 0777)
if err != nil {
return err
}
_, err = io.Copy(fw, tr)
if err != nil{
return err
}
}
return true
}