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  }