filepath.walk 遍历目录需在回调中检查 err 并返回 nil(跳过权限错误)或 filepath.skipdir(跳过目录),避免 panic;不可重复调用 os.stat,不保证顺序且不支持并发,提速应改用 go 1.16+ 的 filepath.walkdir。

如何用 filepath.Walk 遍历目录并避免 panic
直接用 filepath.Walk 时,遇到权限不足或符号链接环会触发 panic 或阻塞——这不是 bug,是默认行为。它会把错误传给回调函数,但如果你没处理返回值,walk 就可能提前退出,漏掉大量文件。
- 必须在 walk 函数中检查
err参数:若为filepath.SkipDir,返回它可跳过子目录;若为其他错误(如os.ErrPermission),建议打印警告但不中断遍历 - 不要在回调里调用
os.Stat二次判断文件类型——info参数已包含完整元信息,重复 stat 会显著拖慢速度 - 注意
filepath.Walk不保证顺序,也不支持并发;如需提速,得自己用filepath.WalkDir(Go 1.16+)配合sync.Pool或 goroutine 控制并发数
用 bufio.Scanner 读文件时怎么防止内存爆炸
对大文件(比如几百 MB 的日志)直接用 strings.Contains 或正则全文加载,极易 OOM。Scanner 默认每行最多 64KB,超长行会直接报错 bufio.Scanner: token too long。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
- 用
scanner.Split(bufio.ScanLines)确保按行切分,避免单次读取过大 - 设置缓冲区:初始化 scanner 前,用
buf := make([]byte, 64*1024)+scanner.Buffer(buf, 1024*1024)控制最大 token 长度(第二个参数是上限,设为 1MB 比较安全) - 别用
scanner.Text()处理二进制文件或含 null 字节的文件——改用scanner.Bytes(),否则会截断
grep 式匹配该选 strings.Contains 还是 regexp
简单字符串搜索用 strings.Contains,快且无开销;一旦需要通配、大小写忽略、行首锚定,就绕不开 regexp。但正则编译成本高,别在循环里反复调用 regexp.Compile。
- 预编译正则:全局变量或闭包内缓存
*regexp.Regexp,例如var re = regexp.MustCompile(<code>pattern) - 大小写不敏感搜索,
strings.Contains(strings.ToLower(line), strings.ToLower(keyword))比正则快 3–5 倍,适合 keyword 固定场景 - 如果要支持
-i、-v、-n等 grep 参数,优先复用regexp.MatchReader或分段处理——MatchReader 能流式匹配,不加载全文
为什么搜索结果里路径显示异常(如 ./dir/../file.txt)
用户输入路径可能是相对路径、带 .. 或 . 的混乱形式,filepath.Walk 传入的路径就是原始路径,不做标准化。直接拼接后输出,会导致路径冗余甚至语义错误。
- 对用户输入的根路径,先调用
filepath.Abs获取绝对路径,再用filepath.Clean规范化(如/a/b/../c→/a/c) - 匹配到的文件路径,用
filepath.Rel(root, fullPath)转成相对于搜索起点的路径,更符合用户直觉 - 注意 Windows 下
filepath.Clean会把/转成\,跨平台输出建议统一用filepath.ToSlash转斜杠
open 和 read 的延迟波动很大。别迷信“算法复杂度”,先压测你的 os.Open 并发数。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










