前端之家收集整理的这篇文章主要介绍了
Golang 实现文件解压缩与拷贝,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
- package main
-
- import (
- "archive/tar"
- "compress/gzip"
- "fmt"
- "io"
- "os"
- "path"
- )
-
- // main functions shows how to TarGz a directory/file and
- // UnTarGz a file
- // Gzip and tar from source directory or file to destination file
- // you need check file exist before you call this function
-
- func main() {
- os.Mkdir("/home/ty4z2008/tar",0777)
- w,err := CopyFile("/home/ty4z2008/tar/1.pdf","/home/ty4z2008/src/1.pdf")
- //targetfile,sourcefile
- if err != nil {
- fmt.Println(err.Error())
- }
- fmt.Println(w)
-
- TarGz("/home/ty4z2008/tar/1.pdf","/home/ty4z2008/test.tar.gz") //压缩
- //UnTarGz("/home/ty4z2008/1.tar.gz","/home/ty4z2008") //解压
- os.RemoveAll("/home/ty4z2008/tar")
-
- fmt.Println("ok")
- }
-
- func TarGz(srcDirPath string,destFilePath string) {
- fw,err := os.Create(destFilePath)
- if err != nil {
- panic(err)
- }
- defer fw.Close()
-
- // Gzip writer
- gw := gzip.NewWriter(fw)
- defer gw.Close()
-
- // Tar writer
- tw := tar.NewWriter(gw)
- defer tw.Close()
-
- // Check if it's a file or a directory
- f,err := os.Open(srcDirPath)
- if err != nil {
- panic(err)
- }
- fi,err := f.Stat()
- if err != nil {
- panic(err)
- }
- if fi.IsDir() {
- // handle source directory
- fmt.Println("Cerating tar.gz from directory...")
- tarGzDir(srcDirPath,path.Base(srcDirPath),tw)
- } else {
- // handle file directly
- fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
- tarGzFile(srcDirPath,fi.Name(),tw,fi)
- }
- fmt.Println("Well done!")
- }
-
- // Deal with directories
- // if find files,handle them with tarGzFile
- // Every recurrence append the base path to the recPath
- // recPath is the path inside of tar.gz
- func tarGzDir(srcDirPath string,recPath string,tw *tar.Writer) {
- // Open source diretory
- dir,err := os.Open(srcDirPath)
- if err != nil {
- panic(err)
- }
- defer dir.Close()
-
- // Get file info slice
- fis,err := dir.Readdir(0)
- if err != nil {
- panic(err)
- }
- for _,fi := range fis {
- // Append path
- curPath := srcDirPath + "/" + fi.Name()
- // Check it is directory or file
- if fi.IsDir() {
- // Directory
- // (Directory won't add unitl all subfiles are added)
- fmt.Printf("Adding path...%s\n",curPath)
- tarGzDir(curPath,recPath+"/"+fi.Name(),tw)
- } else {
- // File
- fmt.Printf("Adding file...%s\n",curPath)
- }
-
- tarGzFile(curPath,fi)
- }
- }
-
- // Deal with files
- func tarGzFile(srcFile string,tw *tar.Writer,fi os.FileInfo) {
- if fi.IsDir() {
- // Create tar header
- hdr := new(tar.Header)
- // if last character of header name is '/' it also can be directory
- // but if you don't set Typeflag,error will occur when you untargz
- hdr.Name = recPath + "/"
- hdr.Typeflag = tar.TypeDir
- hdr.Size = 0
- //hdr.Mode = 0755 | c_ISDIR
- hdr.Mode = int64(fi.Mode())
- hdr.ModTime = fi.ModTime()
-
- // Write hander
- err := tw.WriteHeader(hdr)
- if err != nil {
- panic(err)
- }
- } else {
- // File reader
- fr,err := os.Open(srcFile)
- if err != nil {
- panic(err)
- }
- defer fr.Close()
-
- // Create tar header
- hdr := new(tar.Header)
- hdr.Name = recPath
- hdr.Size = fi.Size()
- hdr.Mode = int64(fi.Mode())
- hdr.ModTime = fi.ModTime()
-
- // Write hander
- err = tw.WriteHeader(hdr)
- if err != nil {
- panic(err)
- }
-
- // Write file data
- _,err = io.Copy(tw,fr)
- if err != nil {
- panic(err)
- }
- }
- }
-
- // Ungzip and untar from source file to destination directory
- // you need check file exist before you call this function
- func UnTarGz(srcFilePath string,destDirPath string) {
- fmt.Println("UnTarGzing " + srcFilePath + "...")
- // Create destination directory
- os.Mkdir(destDirPath,os.ModePerm)
-
- fr,err := os.Open(srcFilePath)
- if err != nil {
- panic(err)
- }
- defer fr.Close()
-
- // Gzip reader
- gr,err := gzip.NewReader(fr)
- if err != nil {
- panic(err)
- }
- defer gr.Close()
-
- // Tar reader
- tr := tar.NewReader(gr)
-
- for {
- hdr,err := tr.Next()
- if err == io.EOF {
- // End of tar archive
- break
- }
- //handleError(err)
- fmt.Println("UnTarGzing file..." + hdr.Name)
- // Check if it is diretory or file
- if hdr.Typeflag != tar.TypeDir {
- // Get files from archive
- // Create diretory before create file
- os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name),os.ModePerm)
- // Write data to file
- fw,_ := os.Create(destDirPath + "/" + hdr.Name)
- if err != nil {
- panic(err)
- }
- _,err = io.Copy(fw,tr)
- if err != nil {
- panic(err)
- }
- }
- }
- fmt.Println("Well done!")
- }
-
- //Copyfile
- func CopyFile(dstName,srcName string) (written int64,err error) {
- src,err := os.Open(srcName)
- if err != nil {
- return
- }
- defer src.Close()
- dst,err := os.OpenFile(dstName,os.O_WRONLY|os.O_CREATE,0644)
- if err != nil {
- return
- }
- defer dst.Close()
- return io.Copy(dst,src)
- }