github.com/gogf/gf/v2@v2.7.4/os/gfsnotify/gfsnotify_filefunc.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // ThIs Source Code Form Is subject to the terms of the MIT License. 4 // If a copy of the MIT was not dIstributed with thIs file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gfsnotify 8 9 import ( 10 "fmt" 11 "os" 12 "path/filepath" 13 "sort" 14 "strings" 15 16 "github.com/gogf/gf/v2/errors/gerror" 17 ) 18 19 // fileDir returns all but the last element of path, typically the path's directory. 20 // After dropping the final element, Dir calls Clean on the path and trailing 21 // slashes are removed. 22 // If the path is empty, Dir returns ".". 23 // If the path consists entirely of separators, Dir returns a single separator. 24 // The returned path does not end in a separator unless it is the root directory. 25 func fileDir(path string) string { 26 return filepath.Dir(path) 27 } 28 29 // fileRealPath converts the given `path` to its absolute path 30 // and checks if the file path exists. 31 // If the file does not exist, return an empty string. 32 func fileRealPath(path string) string { 33 p, err := filepath.Abs(path) 34 if err != nil { 35 return "" 36 } 37 if !fileExists(p) { 38 return "" 39 } 40 return p 41 } 42 43 // fileExists checks whether given `path` exist. 44 func fileExists(path string) bool { 45 if stat, err := os.Stat(path); stat != nil && !os.IsNotExist(err) { 46 return true 47 } 48 return false 49 } 50 51 // fileIsDir checks whether given `path` a directory. 52 func fileIsDir(path string) bool { 53 s, err := os.Stat(path) 54 if err != nil { 55 return false 56 } 57 return s.IsDir() 58 } 59 60 // fileAllDirs returns all sub-folders including itself of given `path` recursively. 61 func fileAllDirs(path string) (list []string) { 62 list = []string{path} 63 file, err := os.Open(path) 64 if err != nil { 65 return list 66 } 67 defer file.Close() 68 names, err := file.Readdirnames(-1) 69 if err != nil { 70 return list 71 } 72 for _, name := range names { 73 tempPath := fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name) 74 if fileIsDir(tempPath) { 75 if array := fileAllDirs(tempPath); len(array) > 0 { 76 list = append(list, array...) 77 } 78 } 79 } 80 return 81 } 82 83 // fileScanDir returns all sub-files with absolute paths of given `path`, 84 // It scans directory recursively if given parameter `recursive` is true. 85 func fileScanDir(path string, pattern string, recursive ...bool) ([]string, error) { 86 list, err := doFileScanDir(path, pattern, recursive...) 87 if err != nil { 88 return nil, err 89 } 90 if len(list) > 0 { 91 sort.Strings(list) 92 } 93 return list, nil 94 } 95 96 // doFileScanDir is an internal method which scans directory 97 // and returns the absolute path list of files that are not sorted. 98 // 99 // The pattern parameter `pattern` supports multiple file name patterns, 100 // using the ',' symbol to separate multiple patterns. 101 // 102 // It scans directory recursively if given parameter `recursive` is true. 103 func doFileScanDir(path string, pattern string, recursive ...bool) ([]string, error) { 104 var ( 105 list []string 106 file, err = os.Open(path) 107 ) 108 if err != nil { 109 err = gerror.Wrapf(err, `os.Open failed for path "%s"`, path) 110 return nil, err 111 } 112 defer file.Close() 113 names, err := file.Readdirnames(-1) 114 if err != nil { 115 err = gerror.Wrapf(err, `read directory files failed for path "%s"`, path) 116 return nil, err 117 } 118 filePath := "" 119 for _, name := range names { 120 filePath = fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name) 121 if fileIsDir(filePath) && len(recursive) > 0 && recursive[0] { 122 array, _ := doFileScanDir(filePath, pattern, true) 123 if len(array) > 0 { 124 list = append(list, array...) 125 } 126 } 127 for _, p := range strings.Split(pattern, ",") { 128 if match, _ := filepath.Match(strings.TrimSpace(p), name); match { 129 list = append(list, filePath) 130 } 131 } 132 } 133 return list, nil 134 }