![](/img/trans.png)
[英]java bufferedReader.readLine() can't read whole file line
[英]Maximum line length for BufferedReader.readLine() in Java?
我使用BufferedReader的readLine()
方法從套接字讀取文本行。
沒有明顯的方法來限制讀取行的長度。
我擔心數據源可能(惡意地或錯誤地)寫入大量數據而沒有任何換行符,這將導致BufferedReader分配無限量的內存。
有沒有辦法避免這種情況? 或者我是否必須自己實現readLine()
的有界版本?
最簡單的方法是實現自己的有界線讀取器。
甚至更簡單,重用此BoundedBufferedReader
類中的代碼。
實際上,編寫與標准方法相同的readLine()
編碼並readLine()
。 處理3種線路終結器CORRECTLY需要一些非常仔細的編碼。 將上述鏈接的不同方法與Sun版本和Apache Harmony版本的BufferedReader進行比較是很有趣的。
注意:我並不完全相信有界版本或Apache版本是100%正確的。 有界版本假定底層流支持標記和重置,這當然不總是正確的。 如果將Apache視為緩沖區中的最后一個字符,則Apache版本似乎預讀一個字符。 當讀取用戶輸入的輸入時,這將在MacOS上中斷。 Sun版本通過設置一個標志來處理這個問題,以便在下一次read...
操作時跳過CR之后導致可能的LF; 即沒有虛假的預讀。
另一個選擇是Apache Commons的BoundedInputStream :
InputStream bounded = new BoundedInputStream(is, MAX_BYTE_COUNT);
BufferedReader reader = new BufferedReader(new InputStreamReader(bounded));
String line = reader.readLine();
也許最簡單的解決方案是采取略微不同的方法。 不是通過限制一個特定讀取來阻止DoS,而是限制讀取的原始數據量。 這樣,只要分配的內存與傳入數據成比例,您就不必擔心每個讀取和循環使用特殊代碼。
您既可以計算Reader
,也可以更適當地計算未解碼的Stream
或等效的。
String的限制是20億個字符。 如果您希望限制更小,則需要自己讀取數據。 您可以從緩沖流中一次讀取一個字符,直到達到限制或新行char。
這有幾種方法:
在BufferedReader
,不使用String readLine()
,而是使用int read(char[] cbuf, int off, int len)
; 然后你可以使用boolean ready()
來查看你是否全部使用構造函數String(byte[] bytes, int offset, int length)
將其轉換為字符串。
如果你不關心空白並且你只想擁有每行最多的字符數,那么Stephen建議的提議非常簡單,
import java.io.BufferedReader;
import java.io.IOException;
public class BoundedReader extends BufferedReader {
private final int bufferSize;
private char buffer[];
BoundedReader(final BufferedReader in, final int bufferSize) {
super(in);
this.bufferSize = bufferSize;
this.buffer = new char[bufferSize];
}
@Override
public String readLine() throws IOException {
int no;
/* read up to bufferSize */
if((no = this.read(buffer, 0, bufferSize)) == -1) return null;
String input = new String(buffer, 0, no).trim();
/* skip the rest */
while(no >= bufferSize && ready()) {
if((no = read(buffer, 0, bufferSize)) == -1) break;
}
return input;
}
}
編輯:這是為了從用戶終端讀取行。 它會阻塞直到下一行,並返回一個bufferSize
-bounded String
; 線路上的任何進一步輸入都將被丟棄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.