前端之家收集整理的这篇文章主要介绍了
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)
}