【问题标题】:Java, Scanning large file, findWithinHorizon(p, 0) throws exception java.lang.StackOverflowErrorJava,扫描大文件,findWithinHorizo​​n(p, 0) 抛出异常 java.lang.StackOverflowError
【发布时间】:2012-11-05 21:07:33
【问题描述】:

以下是我的代码快照,输入文件大小为 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

【问题讨论】:

  • 请发布堆栈跟踪。不是吗?
  • Stackoverflow 是询问堆栈溢出问题的正确地方!抱歉,无法抗拒。

标签: java regex exception java.util.scanner


【解决方案1】:

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

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

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

为了避免正则表达式引擎不必要的回溯,您可以将所有量词设为possessive

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

无论有没有所有格量词,这个正则表达式匹配如下:

【讨论】:

  • 作为一个没有例外的魅力,非常感谢,你是一个大/巨大的帮手,希望它不会在更大的文件上失败,我已经尝试了 300 个 MG 文件并且它可以工作,尽管 JVM 内存使用率非常高 -> 大约 1.5 G ,如果我可以多次投票,我会的!
【解决方案2】:

我认为您可以更轻松地匹配标记本身而不是分隔符。这就是 findWithinHorizon() 方法的真正用途:扫描仪首选操作模式的替代方案,由 hasNextXXX()nextXXX() 方法表示。

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

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

【讨论】:

  • 这个表达式不符合我的需要,我确实附上了描述格式的相关问题的链接。
猜你喜欢
  • 2015-05-07
  • 2010-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多