Java -在一个大文件中查找字符串模式失败



正在进行Spring Batch项目

作为该方法的输入,我们传递了一个大约300万行的巨大文件。我们需要扫描这个文件并过滤没有whitelistedVals list中提到的SQL代码的行。但是我的代码花了太多时间来读取这么大的文件。

public class MyClass {
private static final List<String> whitelistedVals = new ArrayList<>();
static {
whitelistedVals.add("SQL123N");
whitelistedVals.add("SQL2340W");
whitelistedVals.add("SQL3459W");
}
public String getSqlError(String inputFile) {
Pattern r = Pattern.compile("(SQL\d+[A-Z]*)(?s)(.+?)(\n\n|\n\Z)");
Matcher m = r.matcher(inputFile);
String error = "";
while (m.find()) {
String errorCode = m.group(1);
String errorInGroup = errorCode + m.group(2).toUpperCase();
boolean errorsFound = whitelistedVals
.stream()
.noneMatch(x -> x.equalsIgnoreCase(errorCode));
if (errorsFound) {
error += errorInGroup;
}
}
return error;
}
}
有什么建议可以处理这个问题,以加快进程吗?

使用StringBuilder而不是concat(+=)效果非常好。

看起来,整个文件被读取,然后其内容被提供给getSqlError方法,而使用双换行n作为分隔符扫描文件可能会更好。

此外,whitelistedVals为每个匹配流式传输,尽管它们可以集成到模式中。

方法如下所示:

List<String> whitelistedVals = Arrays.asList("123N", "2340W", "3459W");
public static String getSqlError(String inputFile) throws Exception {
Scanner scan = new Scanner(new File(inputFile))
.useDelimiter("\n\n|\n\Z");
final Spliterator<String> splt = Spliterators.spliterator(scan, Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.NONNULL);
Pattern r = Pattern.compile("(SQL(?!(" 
+ whitelistedVals.stream().collect(Collectors.joining("|")) 
+ ")\b)(\d+[A-Z]*))(?s)(.+)");
return StreamSupport.stream(splt, false).onClose(scan::close)
.flatMap(s -> r.matcher(s)
.results() // Stream<MatchResult>
.map(mr -> mr.group(1) + mr.group(4)) // errorCode + error
.map(String::toUpperCase)
) // Stream<String>
.collect(Collectors.joining("n"));
}

最新更新