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  }