自定义fs.File(noLineBreakFile)实现致fs.Glob无匹配,问题何在?
问题原因与解决方案
你的noLineBreakFile没有实现fs.ReadDirFile接口,导致fs.Glob无法遍历目录获取文件列表,所以返回空匹配结果。
具体原因
fs.Glob的工作逻辑是:
- 如果传入的文件系统实现了
fs.Globber接口,会直接调用其Glob方法(embed.FS正好实现了这个接口,所以直接用它的高效实现); - 如果没有实现
fs.Globber,则会使用默认遍历逻辑:打开目录,调用文件的ReadDir方法获取目录下的所有条目,再逐一匹配模式。
你的noLineBreakFS只实现了fs.FS的Open方法,没有实现fs.Globber;同时noLineBreakFile只实现了fs.File的基础方法(Stat/Read/Close),没有实现ReadDir方法。当fs.Glob尝试用默认逻辑遍历目录时,无法读取目录内容,自然找不到任何匹配的文件。
两种修复方案
方案1:让noLineBreakFile实现ReadDir方法
直接转发底层文件的ReadDir调用,因为embed.FS返回的目录文件本身实现了该接口:
func (f *noLineBreakFile) ReadDir(n int) ([]fs.DirEntry, error) { rdFile, ok := f.file.(fs.ReadDirFile) if !ok { return nil, fs.ErrInvalid } return rdFile.ReadDir(n) }
方案2:让noLineBreakFS实现fs.Globber接口
直接复用底层embed.FS的Glob实现,效率更高:
func (fs *noLineBreakFS) Glob(pattern string) ([]string, error) { globber, ok := fs.fs.(fs.Globber) if !ok { // 如果底层FS不支持Glob,回退到默认实现 return fs.Glob(fs, pattern) } return globber.Glob(pattern) }
两种方案任选其一即可解决fs.Glob无匹配的问题,同时你的换行符替换逻辑不受影响。
内容的提问来源于stack exchange,提问作者LuMa
相关产品推荐
相关产品推荐

