// // file_path.go // Copyright (C) 2022 tiglog // // Distributed under terms of the MIT license. // package gfile import ( "os" "path/filepath" "strings" ) const ( // Separator for file system. // It here defines the separator as variable // to allow it modified by developer if necessary. Separator = string(filepath.Separator) // DefaultPermOpen is the default perm for file opening. DefaultPermOpen = os.FileMode(0655) // DefaultPermCopy is the default perm for file/folder copy. DefaultPermCopy = os.FileMode(0755) ) // Exists checks whether given `path` exist. func Exists(path string) bool { if stat, err := os.Stat(path); stat != nil && !os.IsNotExist(err) { return true } return false } // IsDir checks whether given `path` a directory. // Note that it returns false if the `path` does not exist. func IsDir(path string) bool { s, err := os.Stat(path) if err != nil { return false } return s.IsDir() } // Pwd returns absolute path of current working directory. // Note that it returns an empty string if retrieving current // working directory failed. func Pwd() string { path, err := os.Getwd() if err != nil { return "" } return path } // Chdir changes the current working directory to the named directory. // If there is an error, it will be of type *PathError. func Chdir(dir string) (err error) { err = os.Chdir(dir) return } // IsFile checks whether given `path` a file, which means it's not a directory. // Note that it returns false if the `path` does not exist. func IsFile(path string) bool { s, err := os.Stat(path) if err != nil { return false } return !s.IsDir() } // DirNames returns sub-file names of given directory `path`. // Note that the returned names are NOT absolute paths. func DirNames(path string) ([]string, error) { f, err := os.Open(path) if err != nil { return nil, err } list, err := f.Readdirnames(-1) _ = f.Close() if err != nil { return nil, err } return list, nil } // IsReadable checks whether given `path` is readable. func IsReadable(path string) bool { result := true file, err := os.OpenFile(path, os.O_RDONLY, DefaultPermOpen) if err != nil { result = false } file.Close() return result } // Name returns the last element of path without file extension. // Example: // /var/www/file.js -> file // file.js -> file func Name(path string) string { base := filepath.Base(path) if i := strings.LastIndexByte(base, '.'); i != -1 { return base[:i] } return base } // Dir returns all but the last element of path, typically the path's directory. // After dropping the final element, Dir calls Clean on the path and trailing // slashes are removed. // If the `path` is empty, Dir returns ".". // If the `path` is ".", Dir treats the path as current working directory. // If the `path` consists entirely of separators, Dir returns a single separator. // The returned path does not end in a separator unless it is the root directory. func Dir(path string) string { if path == "." { p, _ := filepath.Abs(path) return filepath.Dir(p) } return filepath.Dir(path) } // IsEmpty checks whether the given `path` is empty. // If `path` is a folder, it checks if there's any file under it. // If `path` is a file, it checks if the file size is zero. // // Note that it returns true if `path` does not exist. func IsEmpty(path string) bool { stat, err := os.Stat(path) if err != nil { return true } if stat.IsDir() { file, err := os.Open(path) if err != nil { return true } defer file.Close() names, err := file.Readdirnames(-1) if err != nil { return true } return len(names) == 0 } else { return stat.Size() == 0 } } // Ext returns the file name extension used by path. // The extension is the suffix beginning at the final dot // in the final element of path; it is empty if there is // no dot. // Note: the result contains symbol '.'. // Eg: // main.go => .go // api.json => .json func Ext(path string) string { ext := filepath.Ext(path) if p := strings.IndexByte(ext, '?'); p != -1 { ext = ext[0:p] } return ext } // ExtName is like function Ext, which returns the file name extension used by path, // but the result does not contain symbol '.'. // Eg: // main.go => go // api.json => json func ExtName(path string) string { return strings.TrimLeft(Ext(path), ".") } func GetProjectHome() string { dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { return "" } return dir }