gitee.com/h79/goutils@v1.22.10/common/archive/gzip/gzip.go (about) 1 // Package gzip implements the Archive interface providing gz archiving 2 // and compression. 3 package gzip 4 5 import ( 6 "fmt" 7 fileconfig "gitee.com/h79/goutils/common/file/config" 8 "io" 9 "os" 10 11 gzip "github.com/klauspost/pgzip" 12 ) 13 14 // Archive as gz. 15 type Archive struct { 16 gw *gzip.Writer 17 } 18 19 // New gz archive. 20 func New(target io.Writer) Archive { 21 // the error will be nil since the compression level is valid 22 gw, _ := gzip.NewWriterLevel(target, gzip.BestCompression) 23 return Archive{ 24 gw: gw, 25 } 26 } 27 28 // Close all closeables. 29 func (a Archive) Close() error { 30 if a.gw != nil { 31 err := a.gw.Close() 32 a.gw = nil 33 return err 34 } 35 return nil 36 } 37 38 // Add file to the archive. 39 func (a Archive) Add(f fileconfig.File, stream ...fileconfig.ReaderStream) error { 40 if a.gw.Header.Name != "" { 41 return fmt.Errorf("gzip: failed to add %s, only one file can be archived in gz format", f.Destination) 42 } 43 file, err := os.Open(f.Source) // #nosec 44 if err != nil { 45 return err 46 } 47 defer func(file *os.File) { 48 err = file.Close() 49 if err != nil { 50 } 51 }(file) 52 info, err := file.Stat() 53 if err != nil { 54 return err 55 } 56 if info.IsDir() { 57 return nil 58 } 59 a.gw.Header.Name = f.Destination 60 if f.Info.ParsedMTime.IsZero() { 61 a.gw.Header.ModTime = info.ModTime() 62 } else { 63 a.gw.Header.ModTime = f.Info.ParsedMTime 64 } 65 if _, err = io.Copy(a.gw, file); err != nil { 66 return err 67 } 68 for i := range stream { 69 stream[i].OnReader(file) 70 } 71 return nil 72 }