github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/unzip.go (about) 1 package utils 2 3 import ( 4 "archive/zip" 5 "errors" 6 "io" 7 "os" 8 "strings" 9 ) 10 11 type Unzip struct { 12 zipFile string 13 targetDir string 14 stripPrefix string 15 } 16 17 func NewUnzip(zipFile string, targetDir string, stripPrefix string) *Unzip { 18 return &Unzip{ 19 zipFile: zipFile, 20 targetDir: targetDir, 21 stripPrefix: stripPrefix, 22 } 23 } 24 25 func (this *Unzip) Run() error { 26 if len(this.zipFile) == 0 { 27 return errors.New("zip file should not be empty") 28 } 29 if len(this.targetDir) == 0 { 30 return errors.New("target dir should not be empty") 31 } 32 33 reader, err := zip.OpenReader(this.zipFile) 34 if err != nil { 35 return err 36 } 37 38 defer func() { 39 _ = reader.Close() 40 }() 41 42 for _, file := range reader.File { 43 info := file.FileInfo() 44 filename := file.Name 45 if len(this.stripPrefix) > 0 { 46 filename = strings.TrimPrefix(filename, this.stripPrefix) 47 } 48 target := this.targetDir + "/" + filename 49 50 // 目录 51 if info.IsDir() { 52 stat, err := os.Stat(target) 53 if err != nil { 54 if !os.IsNotExist(err) { 55 return err 56 } else { 57 err = os.MkdirAll(target, info.Mode()) 58 if err != nil { 59 return err 60 } 61 } 62 } else if !stat.IsDir() { 63 err = os.MkdirAll(target, info.Mode()) 64 if err != nil { 65 return err 66 } 67 } 68 continue 69 } 70 71 // 文件 72 err := func(file *zip.File, target string) error { 73 fileReader, err := file.Open() 74 if err != nil { 75 return err 76 } 77 defer func() { 78 _ = fileReader.Close() 79 }() 80 81 fileWriter, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, file.FileInfo().Mode()) 82 if err != nil { 83 return err 84 } 85 defer func() { 86 _ = fileWriter.Close() 87 }() 88 89 _, err = io.Copy(fileWriter, fileReader) 90 return err 91 }(file, target) 92 if err != nil { 93 return err 94 } 95 } 96 97 return nil 98 }