{"id":4161,"date":"2018-11-03T09:29:11","date_gmt":"2018-11-03T01:29:11","guid":{"rendered":"https:\/\/ixyzero.com\/blog\/?p=4161"},"modified":"2018-11-03T09:29:11","modified_gmt":"2018-11-03T01:29:11","slug":"go%e8%af%ad%e8%a8%80%e5%ad%a6%e4%b9%a014-%e5%ae%9e%e7%8e%b0tar-gz%e6%a0%bc%e5%bc%8f%e7%9a%84%e5%8e%8b%e7%bc%a9%e8%a7%a3%e5%8e%8b","status":"publish","type":"post","link":"https:\/\/ixyzero.com\/blog\/archives\/4161.html","title":{"rendered":"Go\u8bed\u8a00\u5b66\u4e60#14-\u5b9e\u73b0tar.gz\u683c\u5f0f\u7684\u538b\u7f29\u89e3\u538b"},"content":{"rendered":"<p>=Start=<\/p>\n<h4 id=\"id-\u6a21\u677f-\u7f18\u7531\uff1a\">\u7f18\u7531\uff1a<\/h4>\n<p>\u5728\u5b66\u4e60Go \u8bed\u8a00\u7684\u8fc7\u7a0b\u4e2d\u6574\u7406\u603b\u7ed3\u4e00\u4e0b\u5e38\u89c1\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\uff0c\u65b9\u4fbf\u4ee5\u540e\u9700\u8981\u7684\u65f6\u5019\u53c2\u8003\u3002<\/p>\n<h4 id=\"id-\u6a21\u677f-\u6b63\u6587\uff1a\">\u6b63\u6587\uff1a<\/h4>\n<h5 id=\"id-\u6a21\u677f-\u53c2\u8003\u89e3\u7b54\uff1a\">\u53c2\u8003\u89e3\u7b54\uff1a<\/h5>\n<p>\u8bdd\u4e0d\u591a\u8bf4\uff0c\u5148\u4e0a\u4ee3\u7801\u3002\u5148\u53ef\u4ee5\u8fd0\u884c\uff0c\u518d\u9010\u6b65\u6309\u9700\u7406\u89e3\u548c\u6539\u8fdb\u3002<\/p>\n<pre class=\"lang:default decode:true\" title=\"\u538b\u7f29&amp;\u89e3\u538b\">package main\r\n\r\nimport (\r\n    \"archive\/tar\"\r\n    \"compress\/gzip\"\r\n    \"flag\"\r\n    \"fmt\"\r\n    \"io\"\r\n    \"log\"\r\n    \"os\"\r\n    \"path\"\r\n)\r\n\r\n\/\/ main functions shows how to TarGz a directory and\r\n\/\/ UnTarGz a file\r\nfunc main() {\r\n    var srcDirPath = *flag.String(\"srcDir\", \"testdata\", \"The source directory name.\")\r\n    var targetFilePath = *flag.String(\"targetName\", \"testdata.tar.gz\", \"The target file name.\")\r\n    flag.Parse()\r\n    fmt.Printf(\"srcDirPath: %s, type: %T\\n\", srcDirPath, srcDirPath)\r\n    fmt.Printf(\"targetFilePath: %s, type: %T\\n\", targetFilePath, targetFilePath)\r\n    TarGz(srcDirPath, targetFilePath) \/\/ \u538b\u7f29\r\n    UnTarGz(targetFilePath, srcDirPath+\"_temp\") \/\/ \u89e3\u538b\r\n}\r\n\r\n\/\/ Gzip and tar from source directory or file to destination file\r\n\/\/ you need check file exist before you call this function\r\nfunc TarGz(srcDirPath string, destFilePath string) {\r\n    fw, err := os.Create(destFilePath)\r\n    handleError(err)\r\n    defer fw.Close()\r\n\r\n    \/\/ Gzip writer\r\n    gw := gzip.NewWriter(fw)\r\n    defer gw.Close()\r\n\r\n    \/\/ Tar writer\r\n    tw := tar.NewWriter(gw)\r\n    defer tw.Close()\r\n\r\n    \/\/ Check if it's a file or a directory\r\n    f, err := os.Open(srcDirPath)\r\n    handleError(err)\r\n    fi, err := f.Stat()\r\n    handleError(err)\r\n    if fi.IsDir() {\r\n        \/\/ handle source directory\r\n        fmt.Println(\"Cerating tar.gz from directory...\")\r\n        tarGzDir(srcDirPath, path.Base(srcDirPath), tw)\r\n    } else {\r\n        \/\/ handle file directly\r\n        fmt.Println(\"Cerating tar.gz from \" + fi.Name() + \"...\")\r\n        tarGzFile(srcDirPath, fi.Name(), tw, fi)\r\n    }\r\n    fmt.Println(\"Well done!\")\r\n}\r\n\r\n\/\/ Deal with directories\r\n\/\/ if find files, handle them with tarGzFile\r\n\/\/ Every recurrence append the base path to the recPath\r\n\/\/ recPath is the path inside of tar.gz\r\nfunc tarGzDir(srcDirPath string, recPath string, tw *tar.Writer) {\r\n    \/\/ Open source diretory\r\n    dir, err := os.Open(srcDirPath)\r\n    handleError(err)\r\n    defer dir.Close()\r\n\r\n    \/\/ Get file info slice\r\n    fis, err := dir.Readdir(0)\r\n    handleError(err)\r\n    for _, fi := range fis {\r\n        \/\/ Append path\r\n        curPath := srcDirPath + \"\/\" + fi.Name()\r\n        \/\/ Check it is directory or file\r\n        if fi.IsDir() {\r\n            \/\/ Directory\r\n            \/\/ (Directory won't add unitl all subfiles are added)\r\n            fmt.Printf(\"Adding path...%s\\\\n\", curPath)\r\n            tarGzDir(curPath, recPath+\"\/\"+fi.Name(), tw)\r\n        } else {\r\n            \/\/ File\r\n            fmt.Printf(\"Adding file...%s\\\\n\", curPath)\r\n        }\r\n\r\n        tarGzFile(curPath, recPath+\"\/\"+fi.Name(), tw, fi)\r\n    }\r\n}\r\n\r\n\/\/ Deal with files\r\nfunc tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {\r\n    if fi.IsDir() {\r\n        \/\/ Create tar header\r\n        hdr := new(tar.Header)\r\n        \/\/ if last character of header name is '\/' it also can be directory\r\n        \/\/ but if you don't set Typeflag, error will occur when you untargz\r\n        hdr.Name = recPath + \"\/\"\r\n        hdr.Typeflag = tar.TypeDir\r\n        hdr.Size = 0\r\n        \/\/hdr.Mode = 0755 | c_ISDIR\r\n        hdr.Mode = int64(fi.Mode())\r\n        hdr.ModTime = fi.ModTime()\r\n\r\n        \/\/ Write hander\r\n        err := tw.WriteHeader(hdr)\r\n        handleError(err)\r\n    } else {\r\n        \/\/ File reader\r\n        fr, err := os.Open(srcFile)\r\n        handleError(err)\r\n        defer fr.Close()\r\n\r\n        \/\/ Create tar header\r\n        hdr := new(tar.Header)\r\n        hdr.Name = recPath\r\n        hdr.Size = fi.Size()\r\n        hdr.Mode = int64(fi.Mode())\r\n        hdr.ModTime = fi.ModTime()\r\n\r\n        \/\/ Write hander\r\n        err = tw.WriteHeader(hdr)\r\n        handleError(err)\r\n\r\n        \/\/ Write file data\r\n        _, err = io.Copy(tw, fr)\r\n        handleError(err)\r\n    }\r\n}\r\n\r\n\/\/ Ungzip and untar from source file to destination directory\r\n\/\/ you need check file exist before you call this function\r\nfunc UnTarGz(srcFilePath string, destDirPath string) {\r\n    fmt.Println(\"UnTarGzing \" + srcFilePath + \"...\")\r\n    \/\/ Create destination directory\r\n    os.Mkdir(destDirPath, os.ModePerm)\r\n\r\n    fr, err := os.Open(srcFilePath)\r\n    handleError(err)\r\n    defer fr.Close()\r\n\r\n    \/\/ Gzip reader\r\n    gr, err := gzip.NewReader(fr)\r\n\r\n    \/\/ Tar reader\r\n    tr := tar.NewReader(gr)\r\n\r\n    for {\r\n        hdr, err := tr.Next()\r\n        if err == io.EOF {\r\n            \/\/ End of tar archive\r\n            break\r\n        }\r\n        \/\/handleError(err)\r\n        fmt.Println(\"UnTarGzing file...\" + hdr.Name)\r\n        \/\/ Check if it is diretory or file\r\n        if hdr.Typeflag != tar.TypeDir {\r\n            \/\/ Get files from archive\r\n            \/\/ Create diretory before create file\r\n            os.MkdirAll(destDirPath+\"\/\"+path.Dir(hdr.Name), os.ModePerm)\r\n            \/\/ Write data to file\r\n            fw, _ := os.Create(destDirPath + \"\/\" + hdr.Name)\r\n            handleError(err)\r\n            _, err = io.Copy(fw, tr)\r\n            handleError(err)\r\n        }\r\n    }\r\n    fmt.Println(\"Well done!\")\r\n}\r\n\r\nfunc handleError(err error) {\r\n    log.Println(err)\r\n}<\/pre>\n<p>&amp;<\/p>\n<pre class=\"lang:default decode:true \">package main\r\n\r\nimport (\r\n    \"archive\/tar\"\r\n    \"compress\/gzip\"\r\n    \"flag\"\r\n    \"fmt\"\r\n    \"io\"\r\n    \"os\"\r\n    \"path\/filepath\"\r\n    \"strings\"\r\n)\r\n\r\nfunc main() {\r\n    var srcDirPath = *flag.String(\"srcDir\", \"testdata\", \"The source directory name.\")\r\n    var targetFilePath = *flag.String(\"targetName\", \"testdata.tar.gz\", \"The target file name.\")\r\n    flag.Parse()\r\n    fmt.Printf(\"srcDirPath: %s, type: %T\\n\", srcDirPath, srcDirPath)\r\n    fmt.Printf(\"targetFilePath: %s, type: %T\\n\", targetFilePath, targetFilePath)\r\n\r\n    TarFilesDirs(srcDirPath, targetFilePath) \/\/ \u4ec5\u538b\u7f29\uff0c\u89e3\u538b\u53ef\u4ee5\u4f7f\u7528tar\u547d\u4ee4\u8fdb\u884c\r\n}\r\n\r\nfunc TarFilesDirs(path string, tarFilePath string) error {\r\n    file, err := os.Create(tarFilePath)\r\n    if err != nil {\r\n        return err\r\n    }\r\n\r\n    defer file.Close()\r\n    gz := gzip.NewWriter(file)\r\n    defer gz.Close()\r\n\r\n    tw := tar.NewWriter(gz)\r\n    defer tw.Close()\r\n\r\n    if err := tarit(path, tw); err != nil {\r\n        return err\r\n    }\r\n\r\n    return nil\r\n}\r\n\r\nfunc tarit(source string, tw *tar.Writer) error {\r\n    info, err := os.Stat(source)\r\n    if err != nil {\r\n        return nil\r\n    }\r\n    var baseDir string\r\n    if info.IsDir() {\r\n        baseDir = filepath.Base(source)\r\n    }\r\n\r\n    return filepath.Walk(source,\r\n        func(path string, info os.FileInfo, err error) error {\r\n            if err != nil {\r\n                return err\r\n            }\r\n\r\n            var link string\r\n            if info.Mode()&amp;os.ModeSymlink != 0 {\r\n                if link, err = os.Readlink(path); err != nil {\r\n                    return err\r\n                }\r\n            }\r\n            header, err := tar.FileInfoHeader(info, link)\r\n            if err != nil {\r\n                return err\r\n            }\r\n            if baseDir != \"\" {\r\n                header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))\r\n            }\r\n\r\n            if !info.Mode().IsRegular() { \/\/nothing more to do for non-regular\r\n                return nil\r\n            }\r\n            if err := tw.WriteHeader(header); err != nil {\r\n                return err\r\n            }\r\n\r\n            if info.IsDir() {\r\n                return nil\r\n            }\r\n\r\n            file, err := os.Open(path)\r\n            if err != nil {\r\n                return err\r\n            }\r\n\r\n            defer file.Close()\r\n\r\n            buf := make([]byte, 16)\r\n            if _, err = io.CopyBuffer(tw, file, buf); err != nil {\r\n                return err\r\n            }\r\n\r\n            return nil\r\n        })\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<h5 id=\"id-\u6a21\u677f-\u53c2\u8003\u94fe\u63a5\uff1a\">\u53c2\u8003\u94fe\u63a5\uff1a<\/h5>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/jonmorehouse\/9060515\">Quick golang script for creating a gzipped tarball<\/a>#\u6d4b\u8bd5OK\uff0c\u4f46\u6bd4\u8f83\u7b80\u5355<\/li>\n<li><a href=\"http:\/\/outofmemory.cn\/code-snippet\/11518\/Go-language-achieve-tar-gz-solution\">Go\u8bed\u8a00\u5b9e\u73b0tar.gz\u6253\u5305\u89e3\u5305<\/a>#\u6d4b\u8bd5OK\uff0c\u7b80\u5355\u52a0\u5de5\u4e4b\u540e\u53ef\u4f7f\u7528<\/li>\n<li><a href=\"https:\/\/www.opsdev.cn\/post\/targz.html\">Golang \u5b9e\u73b0tar.gz\u6253\u5305<\/a>#\u6d4b\u8bd5OK\uff0c\u4e14\u6bd4\u8f83\u7b80\u6d01<\/li>\n<li><a href=\"https:\/\/www.cnblogs.com\/golove\/p\/3454630.html\">\u4ee3\u7801\u7247\u6bb5 &#8211; Golang \u521b\u5efa .tar.gz \u538b\u7f29\u5305<\/a><\/li>\n<li><a href=\"http:\/\/www.nljb.net\/default\/Golang-%E5%8E%8B%E7%BC%A9-%E8%A7%A3%E5%8E%8B-Tar.Gz\/\">Golang-\u538b\u7f29-\u89e3\u538b-Tar.Gz<\/a><\/li>\n<li><a href=\"http:\/\/www.dotcoo.com\/golang-tar-gzip\">golang\u538b\u7f29,\u89e3\u538btar.gz\u6587\u4ef6<\/a><\/li>\n<li><a href=\"https:\/\/www.cnblogs.com\/xiaofengshuyu\/p\/5646494.html\">golang tar gzip \u538b\u7f29\uff0c\u89e3\u538b\uff08\u542b\u76ee\u5f55\u6587\u4ef6\uff09<\/a><\/li>\n<li><a href=\"https:\/\/golang.org\/pkg\/archive\/tar\/\">https:\/\/golang.org\/pkg\/archive\/tar\/<\/a><\/li>\n<li><a href=\"http:\/\/blog.ralch.com\/tutorial\/golang-working-with-tar-and-gzip\/\">Golang: Working with Gzip and Tar<\/a><br \/>\n<a href=\"https:\/\/gist.github.com\/svett\/76799ba2edca89961be6\">https:\/\/gist.github.com\/svett\/76799ba2edca89961be6<\/a><\/li>\n<li><a href=\"https:\/\/golangcaff.com\/articles\/151\/golang-learning-notes-four-archivetar-package-compression-and-decompression\">Golang \u5b66\u4e60\u7b14\u8bb0\uff08\u56db\uff09- archive\/tar \u5b9e\u73b0\u6253\u5305\u538b\u7f29\u53ca\u89e3\u538b<\/a><br \/>\n<a href=\"https:\/\/broqiang.com\/posts\/45\">https:\/\/broqiang.com\/posts\/45<\/a><\/li>\n<li><a href=\"https:\/\/www.kancloud.cn\/liupengjie\/go\/583372\">5.\u538b\u7f29\u6587\u4ef6\u8bfb\u5199<\/a><\/li>\n<\/ul>\n<p>=END=<\/p>\n","protected":false},"excerpt":{"rendered":"<p>=Start= \u7f18\u7531\uff1a \u5728\u5b66\u4e60Go \u8bed\u8a00\u7684\u8fc7\u7a0b\u4e2d\u6574\u7406\u603b\u7ed3\u4e00\u4e0b\u5e38\u89c1\u529f\u80fd\u7684\u5b9e\u73b0\u4ee3\u7801\uff0c\u65b9\u4fbf\u4ee5\u540e\u9700\u8981\u7684\u65f6\u5019\u53c2\u8003\u3002 \u6b63\u6587 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,7,12],"tags":[564,419,211],"class_list":["post-4161","post","type-post","status-publish","format-standard","hentry","category-knowledgebase-2","category-programing","category-tools","tag-golang","tag-gzip","tag-tar"],"views":7314,"_links":{"self":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/4161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/comments?post=4161"}],"version-history":[{"count":1,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/4161\/revisions"}],"predecessor-version":[{"id":4162,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/posts\/4161\/revisions\/4162"}],"wp:attachment":[{"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/media?parent=4161"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/categories?post=4161"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ixyzero.com\/blog\/wp-json\/wp\/v2\/tags?post=4161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}