github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/archiver/tarsz.go (about) 1 package archiver 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 9 "github.com/golang/snappy" 10 ) 11 12 // TarSz is for TarSz format 13 var TarSz tarSzFormat 14 15 func init() { 16 RegisterFormat("TarSz", TarSz) 17 } 18 19 type tarSzFormat struct{} 20 21 func (tarSzFormat) Match(filename string) bool { 22 return strings.HasSuffix(strings.ToLower(filename), ".tar.sz") || strings.HasSuffix(strings.ToLower(filename), ".tsz") || isTarSz(filename) 23 } 24 25 // isTarSz checks the file has the sz compressed Tar format header by 26 // reading its beginning block. 27 func isTarSz(tarszPath string) bool { 28 f, err := os.Open(tarszPath) 29 if err != nil { 30 return false 31 } 32 defer f.Close() 33 34 szr := snappy.NewReader(f) 35 buf := make([]byte, tarBlockSize) 36 n, err := szr.Read(buf) 37 if err != nil || n < tarBlockSize { 38 return false 39 } 40 41 return hasTarHeader(buf) 42 } 43 44 // Write outputs a .tar.sz file to a Writer containing 45 // the contents of files listed in filePaths. File paths 46 // can be those of regular files or directories. Regular 47 // files are stored at the 'root' of the archive, and 48 // directories are recursively added. 49 func (tarSzFormat) Write(output io.Writer, filePaths []string) error { 50 return writeTarSz(filePaths, output, "") 51 } 52 53 // Make creates a .tar.sz file at tarszPath containing 54 // the contents of files listed in filePaths. File paths 55 // can be those of regular files or directories. Regular 56 // files are stored at the 'root' of the archive, and 57 // directories are recursively added. 58 func (tarSzFormat) Make(tarszPath string, filePaths []string) error { 59 out, err := os.Create(tarszPath) 60 if err != nil { 61 return fmt.Errorf("error creating %s: %v", tarszPath, err) 62 } 63 defer out.Close() 64 65 return writeTarSz(filePaths, out, tarszPath) 66 } 67 68 func writeTarSz(filePaths []string, output io.Writer, dest string) error { 69 szw := snappy.NewBufferedWriter(output) 70 defer szw.Close() 71 72 return writeTar(filePaths, szw, dest) 73 } 74 75 // Read untars a .tar.sz file read from a Reader and decompresses 76 // the contents into destination. 77 func (tarSzFormat) Read(input io.Reader, destination string) error { 78 szr := snappy.NewReader(input) 79 80 return Tar.Read(szr, destination) 81 } 82 83 // Open untars source and decompresses the contents into destination. 84 func (tarSzFormat) Open(source, destination string) error { 85 f, err := os.Open(source) 86 if err != nil { 87 return fmt.Errorf("%s: failed to open archive: %v", source, err) 88 } 89 defer f.Close() 90 91 return TarSz.Read(f, destination) 92 }