github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/persistence/problems/utils.go (about)

     1  package problems
     2  
     3  import (
     4  	"archive/zip"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"path/filepath"
     9  )
    10  
    11  type FileNotFoundError struct {
    12  	FileName string
    13  }
    14  
    15  func (e FileNotFoundError) Error() string {
    16  	return fmt.Sprintf("file (%s) not found", e.FileName)
    17  }
    18  
    19  func IsFileNotFoundError(e error) bool {
    20  	_, ok := e.(FileNotFoundError)
    21  	return ok
    22  }
    23  
    24  func NewFileNotFoundError(fileName string) error {
    25  	return FileNotFoundError{FileName: fileName}
    26  }
    27  
    28  func UnZip(zipArchive *zip.ReadCloser, destDir string) error {
    29  	return WalkZip(zipArchive, func(f *zip.File) error {
    30  		fpath := filepath.Join(destDir, f.Name)
    31  		if f.FileInfo().IsDir() {
    32  			_ = os.MkdirAll(fpath, os.ModePerm)
    33  		} else {
    34  			if err := os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
    35  				return err
    36  			}
    37  
    38  			inFile, err := f.Open()
    39  			if err != nil {
    40  				return err
    41  			}
    42  			defer inFile.Close()
    43  
    44  			outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
    45  			if err != nil {
    46  				return err
    47  			}
    48  			defer outFile.Close()
    49  
    50  			_, err = io.Copy(outFile, inFile)
    51  			if err != nil {
    52  				return err
    53  			}
    54  		}
    55  		return nil
    56  	})
    57  }
    58  
    59  func WalkZip(zipArchive *zip.ReadCloser, walkFunc func(file *zip.File) error) error {
    60  	for _, f := range zipArchive.File {
    61  		err := walkFunc(f)
    62  		if err != nil {
    63  			return err
    64  		}
    65  	}
    66  	return nil
    67  }
    68  
    69  // 搜索zip内的文件并打开(精确匹配)
    70  func FindInZip(zipArchive *zip.ReadCloser, fileName string) (*io.ReadCloser, *zip.File, error) {
    71  	var fileResult io.ReadCloser
    72  	finded := false
    73  	var fileInfo *zip.File
    74  	err := WalkZip(zipArchive, func(file *zip.File) error {
    75  		fileInfo = file
    76  		if fileName == file.Name {
    77  			finded = true
    78  			var err error
    79  			fileResult, err = file.Open()
    80  			if err != nil {
    81  				return err
    82  			}
    83  		}
    84  		return nil
    85  	})
    86  	if !finded {
    87  		return nil, nil, NewFileNotFoundError(fileName)
    88  	}
    89  	return &fileResult, fileInfo, err
    90  }