github.com/gogf/gf@v1.16.9/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  
    17  // fileDir returns all but the last element of path, typically the path's directory.
    18  // After dropping the final element, Dir calls Clean on the path and trailing
    19  // slashes are removed.
    20  // If the path is empty, Dir returns ".".
    21  // If the path consists entirely of separators, Dir returns a single separator.
    22  // The returned path does not end in a separator unless it is the root directory.
    23  func fileDir(path string) string {
    24  	return filepath.Dir(path)
    25  }
    26  
    27  // fileRealPath converts the given `path` to its absolute path
    28  // and checks if the file path exists.
    29  // If the file does not exist, return an empty string.
    30  func fileRealPath(path string) string {
    31  	p, err := filepath.Abs(path)
    32  	if err != nil {
    33  		return ""
    34  	}
    35  	if !fileExists(p) {
    36  		return ""
    37  	}
    38  	return p
    39  }
    40  
    41  // fileExists checks whether given `path` exist.
    42  func fileExists(path string) bool {
    43  	if stat, err := os.Stat(path); stat != nil && !os.IsNotExist(err) {
    44  		return true
    45  	}
    46  	return false
    47  }
    48  
    49  // fileIsDir checks whether given `path` a directory.
    50  func fileIsDir(path string) bool {
    51  	s, err := os.Stat(path)
    52  	if err != nil {
    53  		return false
    54  	}
    55  	return s.IsDir()
    56  }
    57  
    58  // fileAllDirs returns all sub-folders including itself of given `path` recursively.
    59  func fileAllDirs(path string) (list []string) {
    60  	list = []string{path}
    61  	file, err := os.Open(path)
    62  	if err != nil {
    63  		return list
    64  	}
    65  	defer file.Close()
    66  	names, err := file.Readdirnames(-1)
    67  	if err != nil {
    68  		return list
    69  	}
    70  	for _, name := range names {
    71  		path := fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name)
    72  		if fileIsDir(path) {
    73  			if array := fileAllDirs(path); len(array) > 0 {
    74  				list = append(list, array...)
    75  			}
    76  		}
    77  	}
    78  	return
    79  }
    80  
    81  // fileScanDir returns all sub-files with absolute paths of given `path`,
    82  // It scans directory recursively if given parameter `recursive` is true.
    83  func fileScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
    84  	list, err := doFileScanDir(path, pattern, recursive...)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	if len(list) > 0 {
    89  		sort.Strings(list)
    90  	}
    91  	return list, nil
    92  }
    93  
    94  // doFileScanDir is an internal method which scans directory
    95  // and returns the absolute path list of files that are not sorted.
    96  //
    97  // The pattern parameter `pattern` supports multiple file name patterns,
    98  // using the ',' symbol to separate multiple patterns.
    99  //
   100  // It scans directory recursively if given parameter `recursive` is true.
   101  func doFileScanDir(path string, pattern string, recursive ...bool) ([]string, error) {
   102  	list := ([]string)(nil)
   103  	file, err := os.Open(path)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	defer file.Close()
   108  	names, err := file.Readdirnames(-1)
   109  	if err != nil {
   110  		return nil, err
   111  	}
   112  	filePath := ""
   113  	for _, name := range names {
   114  		filePath = fmt.Sprintf("%s%s%s", path, string(filepath.Separator), name)
   115  		if fileIsDir(filePath) && len(recursive) > 0 && recursive[0] {
   116  			array, _ := doFileScanDir(filePath, pattern, true)
   117  			if len(array) > 0 {
   118  				list = append(list, array...)
   119  			}
   120  		}
   121  		for _, p := range strings.Split(pattern, ",") {
   122  			if match, err := filepath.Match(strings.TrimSpace(p), name); err == nil && match {
   123  				list = append(list, filePath)
   124  			}
   125  		}
   126  	}
   127  	return list, nil
   128  }