使用BufferedReader读取指定uan消息块时结果缺失问题求助
问题分析与解决方案
你的代码现在只捕获第一个匹配块的原因主要有两个:
- 当你调用
buff.lines().forEach()时,会一次性读取BufferedReader中剩余的所有行,外层的while ((line = buff.readLine()) != null)循环就没有后续行可读了,自然没法处理第二个uan:123的块。 - 用抛出异常的方式跳出forEach循环不仅粗暴,还会直接终止整个程序,根本没机会处理后续内容。
我们可以换一种思路:通过一个状态变量跟踪当前是否处于目标uan的消息块中,逐行处理整个文件,这样就能捕获所有匹配的块。
修正后的代码示例
String targetUan = "uan:123"; String messageBegin = "[MESSAGE BEGIN]"; String messageEnd = "[MESSAGE END]"; List<String> desiredLines = new ArrayList<>(); boolean inMatchingBlock = false; try (BufferedReader buff = Files.newBufferedReader(getPath())) { String line; while ((line = buff.readLine()) != null) { // 检查是否进入一个新的消息块 if (line.contains(messageBegin)) { inMatchingBlock = false; // 重置状态,准备检查当前块是否匹配 // 如果当前块包含目标uan,标记为要收集的块 if (line.contains(targetUan)) { inMatchingBlock = true; // 收集块内的核心内容(去掉MESSAGE BEGIN标记,按需调整) desiredLines.add(line.replace(messageBegin, "").trim()); } } // 如果当前处于匹配的块中,并且不是结束行,收集内容 else if (inMatchingBlock && !line.contains(messageEnd)) { desiredLines.add(line.trim()); } // 遇到块结束,重置状态 else if (line.contains(messageEnd)) { inMatchingBlock = false; } } } catch (IOException e) { e.printStackTrace(); } // 输出结果 desiredLines.forEach(System.out::println);
关键改进点:
- 状态跟踪:用
inMatchingBlock变量记录是否正在处理目标uan的消息块,不会错过任何一个匹配的块。 - 逐行处理:全程用外层while循环逐行读取,不会提前消耗掉所有行,保证能遍历整个文件。
- 优雅的块结束处理:遇到
[MESSAGE END]时重置状态,而不是抛出异常,程序可以正常继续运行。
运行后就能得到你预期的输出:
uan:123 messageID: 111 uan:123 status:test
如果需要保留完整的[MESSAGE BEGIN]和[MESSAGE END]块结构,只需要调整收集行的逻辑,把块的起始和结束行也加入desiredLines即可:
// 当进入匹配块时,收集完整的起始行 if (line.contains(targetUan)) { inMatchingBlock = true; desiredLines.add(line); } // 收集块内内容时保留原行 else if (inMatchingBlock && !line.contains(messageEnd)) { desiredLines.add(line); } // 收集结束行并重置状态 else if (inMatchingBlock && line.contains(messageEnd)) { desiredLines.add(line); inMatchingBlock = false; }
这样输出就会保留完整的块结构:
[MESSAGE BEGIN] uan:123 messageID: 111 [MESSAGE END] [MESSAGE BEGIN] uan:123 status:test [MESSAGE END]
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

