2017-04-01 30 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方法可以提供足夠大的視野以滿足您的需求。掃描儀會在檢索匹配時自動前進。