[英]StringBuilder to Streams and Lambda expressions
我有一個方法:
public String tpeResponse(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder out = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
reader.close();
is.close();
return out.toString();
}
在線: out.append(line);
我有一個錯誤:
java.lang.OutOfMemoryError:Java 堆空間
請幫助我使用 Streams 和 lambda 表達式重建這個方法。
無論你正在閱讀從數據(這is
傳遞到方法變量)或者是
[A] 無窮無盡(例如,如果它是System.in
,它是一個InputStream
代表您的流程標准輸入,並且您使用java -jar yourapp.jar </dev/null
啟動應用程序,那么它實際上是無窮無盡的。
或者,[B]不是無端的,但數據的LOT。 例如,相同的情況,但您執行java -jar yourapp.jar </my/20gigabyte4kCopyOfTheEntireLordOfTheRingsTrilogy.mp4
。
StringBuilder
只是將所有數據存儲在有限的進程內存中。 限制到什么程度? 好吧,當然不會超過您計算機中的 RAM 總量,但通常會少於此數量,這取決於您如何啟動 JVM。 但是,如果您達到了該限制,那么答案是無論如何都不要使用 StringBuilder。
有幾種解決方案。 哪一個是正確的? 從您在問題中提供的有限細節無法判斷:
例如,假設您有一個應用程序,它計算輸入流中“嘿”一詞出現的次數。
而不是像你那樣寫,而是你可以這樣做:
public int countHey(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
int total = 0;
while ((line = reader.readLine()) != null) {
total += countHeyInLine(line);
}
reader.close();
is.close(); // WARNING! SEE BELOW!
return total;
}
即使您向它提供莎士比亞收集的作品,這段代碼也能工作,因為這段代碼讀取一行,處理該行,將此處理的結果減少為單個值,然后繼續:Java 的垃圾收集器可以簡單地收集所有行已經處理了,因此這段代碼將愉快地挖掘你扔給它的所有數百萬行,而不會耗盡內存。
NB:無論打開一個資源還是應該關閉它,或者需要非常清楚地標記它會將關閉它的責任轉移給調用它的人。 您做了相反的操作:此方法不是創建該輸入流的代碼,而是您正在關閉它。 這是一個非常糟糕的主意,會導致資源泄漏。 您不應該關閉is
並在文檔中明確表示您的代碼沒有。 或者,如果您認為最好關閉此方法is
,則它應該在 try/finally 結構中關閉,以便調用者可以放心,調用此方法將最終以一種或另一種方式關閉該流。
使用 try-with-resources 是處理關閉資源的更好方法,當 BufferedReader 關閉時,底層 InputStream 將被關閉
public String tpeResponse(InputStream is) {
StringBuilder out = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
//reader.close(); // no need to close it explicitly
// is.close(); // not needed
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return out.toString();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.