簡體   English   中英

Java - 在大文件中查找字符串模式失敗

[英]Java - Find string pattern in a huge file failing

正在處理 Spring 批處理項目。

作為該方法的輸入,我們傳遞了一個大約 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"));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM