我编写了一个 Java CLI 程序,它从标准输入读取行并为每一行输出一个可能的完成。我正在尝试给它一个 gui,所以我正在尝试构建一个替代品System.in
,以允许用户使用 gui 或 cli。
到目前为止,我得到了这个替换,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也不是一个选项:它不支持追加。