2017-04-01 91 views
1

我有以下的Java代码:保持较大的字符串存储

Path path = Paths.get("largefile.txt2"); 
if (Files.exists(path)) 
    exchange.getIn().setBody(Files.lines(path, Charset.forName("UTF-8")).map(row -> row + System.lineSeparator()).collect(Collectors.joining()).trim()); 
//OOM error! 

我基本上需要读取整个文件在内存中做基于一些搜索性判据各种正则表达式处理和分裂。这些文件可能大到300 MB - 1GB大。

我有这个问题,因为它适用于大约100 MB的文件,但是一旦达到200或更多,我会发现与堆大小相关的内存不足错误.setBody(..)

是否有更高效的内存消耗方法?记忆对我来说比速度更重要。还是我需要重新思考我的整个方法并逐一阅读?

+1

“减少内存消耗的方法”不要将字符串保留在内存中,不要使用正则表达式。也许解析器会起作用? – markspace

+0

我也许可以逃避不把字符串保存在内存中,尽管这意味着重新开始。我仍然不得不使用正则表达式,因为我需要通过各种参数来“清理”数据。你指的是哪种解析器? –

+1

对于大数据,您需要基于流的方法,这意味着您只需在内存中随时保存一小段数据。我认为你真正的问题是不得不用一个巨大的字符串调用'setBody()'。你需要找到一种方法将输出零散地发送到“交换”。 – Bohemian

回答

1

这可能不会有太大帮助,也许可以让您使用更大一点的文件。您需要创建更多的字符串,通过使用以下内容:

row + System.lineSeparator().trim()。你也许可以使用更少的内存,通过改变你的代码位:

exchange.getIn().setBody(Files.lines(path, Charset.forName("UTF-8")).collect(Collectors.joining(System.lineSeparator())); 

虽然我不明白为什么你读一行文件中的行,然后用线再次加入线分隔器。

同样为了用正则表达式处理一个大文件,使用Scanner类和使用扫描仪的findWithinHorizon方法可以提供足够大的视野以满足您的需求。扫描仪会在检索匹配时自动前进。