golib/gfile/file_path.go
2023-07-15 17:52:50 +08:00

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
}