我編寫了一個Java CLI程序,它從stdin讀取行併爲每行輸出一個可能的完成。我試圖給它一個gui,所以我試圖建立一個System.in
的drop-in替換,以允許用戶使用gui或cli。System.in和自定義InputStreamReader之間的行爲差異
到目前爲止,我得到這個置換,其方法add
當文本在JTextArea輸入被稱爲:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.util.LinkedList;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class GuiIn extends InputStream {
protected LinkedBlockingQueue<Byte> buf;
protected boolean closed;
public GuiIn() {
closed = false;
buf = new LinkedBlockingQueue<Byte>();
}
@Override
public void close() {
closed = true;
}
/**
* add strings to read in the InputStream. Arguments are ignored if the
* stream is closed.
*
* @param s
* a string. Ignored if null
*/
public void add(String s) {
if (closed || s == null) {
return;
}
byte[] bs = s.getBytes();
LinkedList<Byte> lbs = new LinkedList<Byte>();
for (byte b : bs) {
lbs.add(b);
}
buf.addAll(lbs);
}
@Override
public int available() {
return buf.size();
}
@Override
public synchronized int read() throws InterruptedIOException {
if (closed && buf.isEmpty()) {
return -1;
}
Byte b = 0;
while (true) {
try {
if ((b = buf.poll(100, TimeUnit.MILLISECONDS)) == null) {
if (closed && buf.isEmpty())
return -1;
} else
break;
} catch (InterruptedException e) {
throw new InterruptedIOException("interrupted: "
+ e.getMessage());
}
}
return b;
}
}
然而,當我嘗試它與new BufferedReader(new InputStreamReader(in));
並試圖readLine()
它,它似乎直到它有足夠的字符(很多),儘管文本饋送總是由我的聽衆附加一個換行符。
另一方面,如果in
設置爲System.in
,則每輸入一行就會讀取一行。
所以,我的問題有兩個部分:
- 哪裏這種差異從何而來?
- 如何解決?
請注意,從每字節裸GuiIn
字節讀取正常工作,而且我已經嘗試過像減少BufferedReader
的緩衝區的大小技巧。
我也在網上預先搜索過:這不是關於創建一個模擬對象;而ByteArrayInputStream也不是一個選項:它不支持追加。你的問題的
好主意抽象圍繞這個問題,雖然這是一個多態性讓步。使用控制檯似乎不太合適,因爲當流重定向時,文檔不能保證存在控制檯(我打算執行批處理來分析許多完成項)。有一件事:這不是關於測試:我已經有JUnit類直接與完成類交互。無論如何,感謝指針! –
@bernardpaulus,是的。這是讓人失望的。我知道默認的'System.out'做了很多非常特定於操作系統的guff,可以用作字節和字符接收器,我懷疑'System.in'類似。如果你抽象,那麼你可以在可用的地方使用'Console',但是當'System.console()== null'時,你可以回到緩衝讀取器周圍的簡單包裝。 –
事實上,它是導致問題的解碼器:openjdk-6的行爲與官方sdk(java 6)的行爲相同,並且通過查看openjdk的源代碼進行了確認。沒有完全通過確切的解碼器類,但那是另一次。再次感謝! –