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) }