实现grep -r功能时日志匹配行显示为二进制的问题排查
问题修复方案
问题根源
- 打开了错误的文件:循环中始终用传入的根目录
path打开文件,而非当前遍历到的文件entry,导致读取目录的二进制垃圾数据写入日志。 - 未过滤目录项:递归遍历会包含子目录,直接读取目录会产生无效内容。
修复后的代码
#include <filesystem> #include <fstream> #include <string> namespace fs = std::filesystem; void showing_all_files(std::string root_path, std::string search) { std::ofstream log_file("grep_ex.log", std::ios::app); // 追加模式避免覆盖,需覆盖则移除std::ios::app if (!log_file.is_open()) { return; } for (const auto & entry : fs::recursive_directory_iterator(root_path)) { // 仅处理普通文件,跳过目录、符号链接等非文件项 if (!entry.is_regular_file()) { continue; } int line_no = 0; std::string line; std::ifstream infile(entry.path()); // 打开当前遍历到的目标文件 if (!infile.is_open()) { continue; } while(std::getline(infile, line)) { ++line_no; auto pos = line.find(search); if(pos != std::string::npos) { log_file << entry.path().string() << ":" << line_no << ":" << line << std::endl; } } } log_file.close(); }
关键修改点
- 修正文件路径:将
ifstream infile(path);改为ifstream infile(entry.path());,确保读取遍历到的目标文件。 - 过滤非普通文件:添加
if (!entry.is_regular_file()) continue;,跳过无法按行读取的目录、设备文件等。 - 添加打开校验:对日志文件和目标文件增加
is_open()检查,处理权限不足等异常情况。 - 明确路径输出格式:用
entry.path().string()替代直接输出entry,避免路径的格式混乱。 - 日志写入模式:用
std::ios::app实现追加写入,若需每次运行覆盖旧日志则移除该参数。
内容的提问来源于stack exchange,提问作者persona
相关产品推荐
相关产品推荐

