如何提取含指定关键词的日志行并写入文件?及Java代码问题咨询
解决.log文件关键词提取及字符空格问题
一、完善代码实现需求
你当前的代码已经搭好了遍历文件夹和读取文件的基础框架,但还需要补充关键词匹配、正确写入结果(包含文件路径和行号)的核心逻辑,同时修正几个明显的逻辑漏洞:
主要问题与修正方向:
- 输出文件被重复覆盖:每次调用
parseFile都新建PrintWriter,会清空之前的提取结果,需要改用追加模式写入; - 文件夹创建重复执行:
folderError.mkdir()放在循环里会每读一行就执行一次,移到循环外即可,推荐用mkdirs()确保父目录不存在时也能创建成功; - 行读取逻辑错误:当前代码先读一行,然后输出下一行,会导致第一行丢失,且最后一行会输出
null; - 缺少关键词匹配逻辑:需要判断每行是否包含你指定的三个关键词中的任意一个。
修正后的完整代码:
import java.io.*; public class LogExtractor { // 替换成你的三个目标关键词 private static final String[] KEYWORDS = {"error", "warning", "critical"}; // 输出文件夹和结果文件名 private static final String OUTPUT_FOLDER = "ErrorFolder"; private static final String OUTPUT_FILE = "extracted_logs.txt"; public static void main(String[] args) { File rootFolder = new File("your_root_folder_path"); // 替换为你的日志根文件夹路径 if (!rootFolder.exists() || !rootFolder.isDirectory()) { System.out.println("指定的文件夹不存在或不是合法目录"); return; } // 提前创建输出文件夹 File outputDir = new File(OUTPUT_FOLDER); if (!outputDir.exists()) { outputDir.mkdirs(); // 创建多级目录,避免父目录不存在的问题 } listAllFilesForFolder(rootFolder); System.out.println("提取完成!结果文件路径:" + OUTPUT_FOLDER + "/" + OUTPUT_FILE); } public static void listAllFilesForFolder(File folder) { File[] fileEntries = folder.listFiles(); if (fileEntries == null) { // 处理权限不足或空文件夹的情况 return; } for (File fileEntry : fileEntries) { if (fileEntry.isDirectory()) { listAllFilesForFolder(fileEntry); } else { String filePath = fileEntry.getAbsolutePath(); // 只处理.log后缀的文件 if (filePath.toLowerCase().endsWith(".log")) { System.out.println("正在处理文件:" + filePath); parseFile(filePath); } } } } public static void parseFile(String filePath) { BufferedReader reader = null; PrintWriter writer = null; try { // 指定文件编码读取,避免乱码(根据你的日志实际编码调整,比如UTF-8、GBK) reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8")); // 追加模式写入结果文件,避免覆盖之前的内容 writer = new PrintWriter(new FileWriter(new File(OUTPUT_FOLDER, OUTPUT_FILE), true)); int lineCount = 0; String currentLine; while ((currentLine = reader.readLine()) != null) { lineCount++; // 判断当前行是否包含任意一个关键词 boolean hasTargetKeyword = false; for (String keyword : KEYWORDS) { if (currentLine.contains(keyword)) { hasTargetKeyword = true; break; } } if (hasTargetKeyword) { // 按「文件路径 | 行号 | 行内容」的格式写入 writer.printf("%s | 第%d行 | %s%n", filePath, lineCount, currentLine); } } } catch (IOException e) { System.err.println("处理文件时出错:" + filePath); e.printStackTrace(); } finally { // 确保流资源被正确关闭 try { if (reader != null) reader.close(); if (writer != null) writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
代码细节说明:
- 用常量存储关键词和输出路径,后续修改更方便;
- 增加了
.log文件的过滤,避免处理无关文件; - 用
printf格式化输出内容,结果可读性更强; - 完善了异常处理,增加了错误提示,同时确保流资源被正确关闭;
- 指定文件编码读取,既能避免乱码,也可能解决你遇到的字符空格问题。
二、字符间出现空格的原因排查
你提到运行代码时字符间出现空格,最常见的原因是文件编码不匹配:
- 如果你的.log文件是UTF-16编码(比如Unicode小端/大端格式),但用默认的
FileReader(依赖系统默认编码,通常是UTF-8或GBK)读取,就会把每个UTF-16字符拆成两个独立字节,导致显示时出现空格; - 解决方法:在代码中指定和日志文件一致的编码读取,比如上面代码中用
InputStreamReader指定"UTF-16"(根据你的实际文件编码调整,可通过Notepad++等工具查看日志文件的编码)。
其他可能的原因:
- 日志文件本身就包含多余空格,可以对比原文件和代码输出的内容排除这个可能;
- 控制台输出的格式问题,但如果写入文件也有空格,就可以排除这个情况。
建议先检查日志文件的编码,再调整代码中的读取编码,应该能解决空格问题。
内容的提问来源于stack exchange,提问作者Tolga
相关产品推荐
相关产品推荐

