github.com/kaydxh/golang@v0.0.131/go/os/file.go (about)

     1  /*
     2   *Copyright (c) 2022, kaydxh
     3   *
     4   *Permission is hereby granted, free of charge, to any person obtaining a copy
     5   *of this software and associated documentation files (the "Software"), to deal
     6   *in the Software without restriction, including without limitation the rights
     7   *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   *copies of the Software, and to permit persons to whom the Software is
     9   *furnished to do so, subject to the following conditions:
    10   *
    11   *The above copyright notice and this permission notice shall be included in all
    12   *copies or substantial portions of the Software.
    13   *
    14   *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    20   *SOFTWARE.
    21   */
    22  package os
    23  
    24  import (
    25  	"fmt"
    26  	"os"
    27  	"path/filepath"
    28  	"strings"
    29  )
    30  
    31  func PathExist(path string) (bool, error) {
    32  	_, err := os.Stat(path)
    33  	if err == nil {
    34  		return true, nil
    35  	}
    36  	if os.IsNotExist(err) {
    37  		return false, nil
    38  	}
    39  	return false, err
    40  
    41  }
    42  
    43  func IsDir(path string) (bool, error) {
    44  	fi, err := os.Stat(path)
    45  	if err != nil {
    46  		return false, err
    47  	}
    48  
    49  	return fi.IsDir(), nil
    50  }
    51  
    52  func IsHidden(path string) (bool, error) {
    53  	_, err := os.Stat(path)
    54  	if err != nil {
    55  		return false, err
    56  	}
    57  
    58  	base := filepath.Base(path)
    59  	if base == "." || base == ".." {
    60  		return false, nil
    61  	}
    62  	if len(base) > 0 && base[0] == '.' {
    63  		return true, nil
    64  	}
    65  
    66  	return false, nil
    67  }
    68  
    69  // MkdirAll creates a directory named path,
    70  // along with any necessary parents, and returns nil,
    71  // or else returns an error.
    72  // The permission(0755) bits perm (before umask) are used for all
    73  // directories that MkdirAll creates.
    74  // If path is already a directory, MkdirAll does nothing
    75  func MakeDirAll(name string) error {
    76  	return os.MkdirAll(name, 0755)
    77  }
    78  
    79  func MakeDir(name string) error {
    80  	return os.Mkdir(name, 0755)
    81  }
    82  
    83  // if name is empty, create a directory named name, or creates a new temporary directory in the directory dir
    84  // pattern can be empty
    85  func MakeTempDirAll(name, pattern string) (string, error) {
    86  	if name != "" {
    87  		// make base dir, or if the dir is not exist, MakeTempDirAll return error
    88  		err := MakeDirAll(name)
    89  		if err != nil {
    90  			return "", err
    91  		}
    92  	}
    93  
    94  	return os.MkdirTemp(name, pattern)
    95  }
    96  
    97  func OpenAll(path string, flag int, perm os.FileMode) (*os.File, error) {
    98  	dir, file := filepath.Split(path)
    99  	// file or dir exists
   100  	if _, err := os.Stat(path); err == nil {
   101  		return os.OpenFile(path, flag, perm)
   102  	}
   103  
   104  	// mkdir -p dir
   105  	if dir != "" {
   106  		if err := MakeDirAll(dir); err != nil {
   107  			return nil, err
   108  		}
   109  	}
   110  
   111  	if file == "" {
   112  		return nil, nil
   113  	}
   114  
   115  	return os.OpenFile(path, flag, perm)
   116  }
   117  
   118  func OpenFile(path string, appended bool) (file *os.File, err error) {
   119  	if !appended {
   120  		file, err = OpenAll(path, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
   121  	} else {
   122  		file, err = OpenAll(path, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
   123  	}
   124  
   125  	return file, err
   126  
   127  }
   128  
   129  // SameFile reports whether fi1 and fi2 describe the same file.
   130  func SameFile(fi1, fi2 string) bool {
   131  	stat1, err := os.Stat(fi1)
   132  	if err != nil {
   133  		return false
   134  	}
   135  
   136  	stat2, err := os.Stat(fi2)
   137  	if err != nil {
   138  		return false
   139  	}
   140  	return os.SameFile(stat1, stat2)
   141  }
   142  
   143  // oldname and newname is full path
   144  func SymLink(oldname, newname string) error {
   145  
   146  	oldname, err := filepath.Abs(oldname)
   147  	if err != nil {
   148  		return err
   149  	}
   150  	newname, err = filepath.Abs(newname)
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	_, err = os.Stat(oldname)
   156  	if err != nil {
   157  		return fmt.Errorf("failed to stat oldname: %v, err: %v", oldname, err)
   158  	}
   159  
   160  	linkdir := filepath.Dir(newname)
   161  	err = MakeDirAll(linkdir)
   162  	if err != nil {
   163  		return fmt.Errorf("failed to make dir: %v, err: %v", linkdir, err)
   164  	}
   165  
   166  	// check link file is valid
   167  	targetname, err := os.Readlink(newname)
   168  	if err == nil {
   169  		if targetname == oldname {
   170  			return nil
   171  		}
   172  	}
   173  	//link file is invalid
   174  	os.Remove(newname)
   175  	/*
   176  		_, err = os.Stat(newname)
   177  		if err != nil {
   178  			if os.IsNotExist(err) {
   179  				os.Remove(newname)
   180  			}
   181  		}
   182  	*/
   183  	err = os.Symlink(oldname, newname)
   184  	if err != nil {
   185  		return fmt.Errorf("failed to symlink err: %v", err)
   186  	}
   187  
   188  	_, err = os.Lstat(newname)
   189  	if err != nil {
   190  		return fmt.Errorf("failed to stat newname: %v, err: %v", newname, err)
   191  	}
   192  
   193  	return err
   194  }
   195  
   196  // include subdir, file and hidden file
   197  func ReadDirNames(path string, filterHiddenFile bool) ([]string, error) {
   198  	file, err := os.Open(path)
   199  	if err != nil {
   200  		return nil, err
   201  	}
   202  	defer file.Close()
   203  
   204  	names, err := file.Readdirnames(-1)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  
   209  	if !filterHiddenFile {
   210  		return names, nil
   211  	}
   212  
   213  	noHiddenFiles := []string{}
   214  
   215  	for _, name := range names {
   216  		if strings.HasPrefix(filepath.Base(name), ".") {
   217  			continue
   218  		}
   219  
   220  		noHiddenFiles = append(noHiddenFiles, name)
   221  
   222  	}
   223  
   224  	return noHiddenFiles, nil
   225  
   226  }
   227  
   228  // only inlcude subdir
   229  // filterHiddenFile  is true, then filter hidden files from result
   230  func ReadDirSubDirNames(path string, filterHiddenFile bool) ([]string, error) {
   231  	names, err := ReadDirNames(path, filterHiddenFile)
   232  	if err != nil {
   233  		return nil, err
   234  	}
   235  
   236  	dirs := []string{}
   237  	for _, name := range names {
   238  
   239  		filePath := filepath.Join(path, name)
   240  		ok, _ := IsDir(filePath)
   241  		if ok {
   242  			dirs = append(dirs, name)
   243  		}
   244  	}
   245  
   246  	return dirs, nil
   247  }
   248  
   249  func ReadDirFileNames(path string, filterHiddenFile bool) ([]string, error) {
   250  	names, err := ReadDirNames(path, filterHiddenFile)
   251  	if err != nil {
   252  		return nil, err
   253  	}
   254  
   255  	dirs := []string{}
   256  	for _, name := range names {
   257  
   258  		filePath := filepath.Join(path, name)
   259  		ok, err := IsDir(filePath)
   260  		if err == nil && !ok {
   261  			dirs = append(dirs, name)
   262  		}
   263  	}
   264  
   265  	return dirs, nil
   266  }