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 }