187 lines
4.4 KiB
Go
187 lines
4.4 KiB
Go
//
|
|
// file_path.go
|
|
// Copyright (C) 2022 tiglog <me@tiglog.com>
|
|
//
|
|
// 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
|
|
}
|