github.com/qjfoidnh/BaiduPCS-Go@v0.0.0-20231011165705-caa18a3765f3/pcsutil/file.go (about)

     1  package pcsutil
     2  
     3  import (
     4  	"github.com/kardianos/osext"
     5  	"github.com/qjfoidnh/BaiduPCS-Go/pcsverbose"
     6  	"os"
     7  	"path"
     8  	"path/filepath"
     9  	"runtime"
    10  	"strings"
    11  )
    12  
    13  func IsPipeInput() bool {
    14  	fileInfo, err := os.Stdin.Stat()
    15  	if err != nil {
    16  		return false
    17  	}
    18  	return (fileInfo.Mode() & os.ModeNamedPipe) == os.ModeNamedPipe
    19  }
    20  
    21  // IsIPhoneOS 是否为苹果移动设备
    22  func IsIPhoneOS() bool {
    23  	if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
    24  		_, err := os.Stat("Info.plist")
    25  		return err == nil
    26  	}
    27  	return false
    28  }
    29  
    30  // ChWorkDir 切换回工作目录
    31  func ChWorkDir() {
    32  	if !IsIPhoneOS() {
    33  		return
    34  	}
    35  
    36  	dir, err := filepath.Abs("")
    37  	if err != nil {
    38  		return
    39  	}
    40  
    41  	subPath := filepath.Dir(os.Args[0])
    42  	os.Chdir(strings.TrimSuffix(dir, subPath))
    43  }
    44  
    45  // Executable 获取程序所在的真实目录或真实相对路径
    46  func Executable() string {
    47  	executablePath, err := osext.Executable()
    48  	if err != nil {
    49  		pcsverbose.Verbosef("DEBUG: osext.Executable: %s\n", err)
    50  		executablePath, err = filepath.Abs(filepath.Dir(os.Args[0]))
    51  		if err != nil {
    52  			pcsverbose.Verbosef("DEBUG: filepath.Abs: %s\n", err)
    53  			executablePath = filepath.Dir(os.Args[0])
    54  		}
    55  	}
    56  
    57  	if IsIPhoneOS() {
    58  		executablePath = filepath.Join(strings.TrimSuffix(executablePath, os.Args[0]), filepath.Base(os.Args[0]))
    59  	}
    60  
    61  	// 读取链接
    62  	linkedExecutablePath, err := filepath.EvalSymlinks(executablePath)
    63  	if err != nil {
    64  		pcsverbose.Verbosef("DEBUG: filepath.EvalSymlinks: %s\n", err)
    65  		return executablePath
    66  	}
    67  	return linkedExecutablePath
    68  }
    69  
    70  // ExecutablePath 获取程序所在目录
    71  func ExecutablePath() string {
    72  	return filepath.Dir(Executable())
    73  }
    74  
    75  // ExecutablePathJoin 返回程序所在目录的子目录
    76  func ExecutablePathJoin(subPath string) string {
    77  	return filepath.Join(ExecutablePath(), subPath)
    78  }
    79  
    80  // WalkDir 获取指定目录及所有子目录下的所有文件,可以匹配后缀过滤。
    81  // 支持 Linux/macOS 软链接
    82  func WalkDir(dirPth, suffix string) (files []string, err error) {
    83  	files = make([]string, 0, 32)
    84  	suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
    85  
    86  	var walkFunc filepath.WalkFunc
    87  	walkFunc = func(filename string, fi os.FileInfo, err error) error { //遍历目录
    88  		if err != nil {
    89  			return err
    90  		}
    91  		if fi.IsDir() || fi.Size() == 0 { // 忽略目录和空文件
    92  			return nil
    93  		}
    94  		if fi.Mode()&os.ModeSymlink != 0 { // 读取 symbol link
    95  			err = filepath.Walk(filename+string(os.PathSeparator), walkFunc)
    96  			return err
    97  		}
    98  
    99  		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
   100  			files = append(files, path.Clean(filename))
   101  		}
   102  		return nil
   103  	}
   104  
   105  	err = filepath.Walk(dirPth, walkFunc)
   106  	return files, err
   107  }
   108  
   109  // ConvertToUnixPathSeparator 将 windows 目录分隔符转换为 Unix 的
   110  func ConvertToUnixPathSeparator(p string) string {
   111  	return strings.Replace(p, "\\", "/", -1)
   112  }
   113  
   114  func ChPathLegal(p string) bool {
   115  	illegal_chars := "<>|:\"*?,\\"
   116  	if runtime.GOOS == "windows" {
   117  		illegal_chars = "<>|\"*?,\\"
   118  	}
   119  
   120  	if strings.ContainsAny(p, illegal_chars) {
   121  		return false
   122  	}
   123  	return true
   124  }