Go(Golang)如何查找匹配的文件系统对象并判断输入路径类型
解决方案
你当前实现的核心问题是将「Glob匹配结果数量」作为判定是否为匹配模式的唯一依据,忽略了「输入路径本身是否包含通配符」这个核心判断维度,同时还存在路径调用错误:当输入路径带通配符时,直接将带通配符的原始路径传入os.Stat必然会返回不存在,只有取Glob返回的匹配结果路径调用os.Stat才有效。
另外需要先明确:filepath.Glob处理的是Shell Glob匹配模式,不是正则表达式,二者语法规则有明显差异。
优化思路
- 第一步:先判断输入路径是否包含未转义的Glob元字符(
*、?、[),只要存在未转义的元字符,就属于匹配模式,和匹配结果数量无关 - 第二步:根据是否为匹配模式走不同分支处理:
- 非匹配模式:直接调用
os.Stat判断路径是文件、目录还是不存在 - 匹配模式:调用
filepath.Glob获取匹配结果,根据匹配结果数量返回对应信息
- 非匹配模式:直接调用
优化后实现代码
package main import ( "os" "path/filepath" ) // 判断路径是否包含未转义的Glob元字符 func hasGlobMeta(path string) bool { escape := false for _, c := range path { if escape { escape = false continue } switch c { case '\\': escape = true case '*', '?', '[': return true } } return false } func getPathType(path string) (exists bool, pathType string, matches []string, err error) { cpath := filepath.Clean(path) // 先判断是否为匹配模式 if hasGlobMeta(cpath) { matches, err = filepath.Glob(cpath) if err != nil { return false, "", nil, err } if len(matches) == 0 { return false, "glob", matches, nil } return true, "glob", matches, nil } // 普通路径直接判断类型 fsstat, err := os.Stat(cpath) if err != nil { if os.IsNotExist(err) { return false, "", nil, nil } return false, "", nil, err } if fsstat.IsDir() { return true, "dir", []string{cpath}, nil } return true, "file", []string{cpath}, nil }
效果说明
- 输入
/path/to/filename.ext:无通配符,直接判定为文件/目录/不存在 - 输入
/path/to/*.txt:包含*元字符,不管匹配到1个还是多个结果,都会判定为glob模式,同时返回所有匹配的路径列表 - 特殊场景:如果文件名本身包含
*等元字符,只要输入时做了转义(如/path/to/abc\*.txt),会被判定为普通路径,不会识别为匹配模式
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

