github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/internal/build/archive.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package build 26 27 import ( 28 "archive/tar" 29 "archive/zip" 30 "compress/gzip" 31 "fmt" 32 "io" 33 "os" 34 "path/filepath" 35 "strings" 36 ) 37 38 type Archive interface { 39 //目录将新目录项添加到存档并设置 40 //用于随后调用头的目录。 41 Directory(name string) error 42 43 //头将新文件添加到存档。文件被添加到目录中 44 //按目录设置。文件的内容必须写入返回的 45 //作家。 46 Header(os.FileInfo) (io.Writer, error) 47 48 //关闭将刷新存档并关闭基础文件。 49 Close() error 50 } 51 52 func NewArchive(file *os.File) (Archive, string) { 53 switch { 54 case strings.HasSuffix(file.Name(), ".zip"): 55 return NewZipArchive(file), strings.TrimSuffix(file.Name(), ".zip") 56 case strings.HasSuffix(file.Name(), ".tar.gz"): 57 return NewTarballArchive(file), strings.TrimSuffix(file.Name(), ".tar.gz") 58 default: 59 return nil, "" 60 } 61 } 62 63 //addfile将现有文件追加到存档。 64 func AddFile(a Archive, file string) error { 65 fd, err := os.Open(file) 66 if err != nil { 67 return err 68 } 69 defer fd.Close() 70 fi, err := fd.Stat() 71 if err != nil { 72 return err 73 } 74 w, err := a.Header(fi) 75 if err != nil { 76 return err 77 } 78 if _, err := io.Copy(w, fd); err != nil { 79 return err 80 } 81 return nil 82 } 83 84 //WriteArchive创建包含给定文件的存档。 85 func WriteArchive(name string, files []string) (err error) { 86 archfd, err := os.Create(name) 87 if err != nil { 88 return err 89 } 90 91 defer func() { 92 archfd.Close() 93 //失败时删除半写存档。 94 if err != nil { 95 os.Remove(name) 96 } 97 }() 98 archive, basename := NewArchive(archfd) 99 if archive == nil { 100 return fmt.Errorf("unknown archive extension") 101 } 102 fmt.Println(name) 103 if err := archive.Directory(basename); err != nil { 104 return err 105 } 106 for _, file := range files { 107 fmt.Println(" +", filepath.Base(file)) 108 if err := AddFile(archive, file); err != nil { 109 return err 110 } 111 } 112 return archive.Close() 113 } 114 115 type ZipArchive struct { 116 dir string 117 zipw *zip.Writer 118 file io.Closer 119 } 120 121 func NewZipArchive(w io.WriteCloser) Archive { 122 return &ZipArchive{"", zip.NewWriter(w), w} 123 } 124 125 func (a *ZipArchive) Directory(name string) error { 126 a.dir = name + "/" 127 return nil 128 } 129 130 func (a *ZipArchive) Header(fi os.FileInfo) (io.Writer, error) { 131 head, err := zip.FileInfoHeader(fi) 132 if err != nil { 133 return nil, fmt.Errorf("can't make zip header: %v", err) 134 } 135 head.Name = a.dir + head.Name 136 head.Method = zip.Deflate 137 w, err := a.zipw.CreateHeader(head) 138 if err != nil { 139 return nil, fmt.Errorf("can't add zip header: %v", err) 140 } 141 return w, nil 142 } 143 144 func (a *ZipArchive) Close() error { 145 if err := a.zipw.Close(); err != nil { 146 return err 147 } 148 return a.file.Close() 149 } 150 151 type TarballArchive struct { 152 dir string 153 tarw *tar.Writer 154 gzw *gzip.Writer 155 file io.Closer 156 } 157 158 func NewTarballArchive(w io.WriteCloser) Archive { 159 gzw := gzip.NewWriter(w) 160 tarw := tar.NewWriter(gzw) 161 return &TarballArchive{"", tarw, gzw, w} 162 } 163 164 func (a *TarballArchive) Directory(name string) error { 165 a.dir = name + "/" 166 return a.tarw.WriteHeader(&tar.Header{ 167 Name: a.dir, 168 Mode: 0755, 169 Typeflag: tar.TypeDir, 170 }) 171 } 172 173 func (a *TarballArchive) Header(fi os.FileInfo) (io.Writer, error) { 174 head, err := tar.FileInfoHeader(fi, "") 175 if err != nil { 176 return nil, fmt.Errorf("can't make tar header: %v", err) 177 } 178 head.Name = a.dir + head.Name 179 if err := a.tarw.WriteHeader(head); err != nil { 180 return nil, fmt.Errorf("can't add tar header: %v", err) 181 } 182 return a.tarw, nil 183 } 184 185 func (a *TarballArchive) Close() error { 186 if err := a.tarw.Close(); err != nil { 187 return err 188 } 189 if err := a.gzw.Close(); err != nil { 190 return err 191 } 192 return a.file.Close() 193 }