Java,扫描大文件,findWithinHorizo​​n(p,0)抛出异常java.lang.StackOverflowError

时间:2012-11-05 21:07:34

标签: java regex exception java.util.scanner

以下是我的代码的快照,输入文件大小为45 Mb

Scanner fileScanner = new Scanner(file);
String scannedFarm;
try{

    Pattern p = Pattern.compile("^(?:.+(?:\\r?\\n|\\Z)){2,}",Pattern.MULTILINE);

    while((scannedFarm = fileScanner.findWithinHorizon(p, 0)) != null){ // Throws Exception
    ...
    ...

我将添加任何可能澄清抛出异常原因的其他信息。 描述文件格式的相关问题可能有所帮助:Java, Regular Expression HasNext starts with empty line, multi-platform support

顺便说一句:这适用于像魅力这样的小文件,大一点就失败了,字符串是否有从findWithinHorizo​​n返回的最大大小?

更新

按要求提供小堆栈跟踪:

http://pastebin.com/dcJ1jdkf

文件快照的一个小例子:

http://pastebin.com/EYMsbrKj

2 个答案:

答案 0 :(得分:3)

我不知道Scanner类的工作原理,但无论.findwithinHorizon()对正则表达式的作用如何,这个正则表达式都非常奇怪。

此正则表达式将立即匹配整个文件,只要每行至少有一个字符长。如果有空行,则它将匹配跨越至少两行的空行之间的所有块。如果那是你真正打算做的,那么有更好的方法:

Pattern p = Pattern.compile("(?:^.+$(?:\\r?\\n)?){2,}", Pattern.MULTILINE);

为了避免对正则表达式引擎进行不必要的回溯,您可以制作所有量词possessive

Pattern p = Pattern.compile("(?:^.++$(?:\\r?+\\n)?+){2,}+", Pattern.MULTILINE);

有或没有占有量词,这个正则表达式匹配如下:

Screenshot RegexBuddy

答案 1 :(得分:0)

我认为你可以更轻松地匹配令牌本身而不是分隔符。这就是findWithinHorizon()方法的用途:替代Scanner的首选操作模式,由hasNextXXX()nextXXX()方法表示。

"(?m)^\\w+;\\w+$(?:\r?\n\\w+(?:;\\w+)+$)+"

您还没有详细说明您的数据格式,所以我只使用了与您的样本匹配的最简单的正则表达式。