我编写了一个Java CLI程序,它从stdin读取行并为每行输出可能的完成。我试图给它一个gui,所以我试图为System.in
构建一个替代品,允许用户使用gui或cli。
到目前为止,我得到了这个替代品,当在JTextArea中输入文本时调用其方法add
:
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也不是一个选项:它不支持追加。
答案 0 :(得分:2)
您的问题的一个来源可能是InputStreamReader
可能会坚持提前阅读,以便确保它使用的byte
- &gt; char
解码器(以及哪些是不透明的)它有足够的字节来产生一个完整的char
,而System.in
可能已经足够了解默认编码以提供足够的字节。
在开始使用Java的交互式控制台之前,您应该熟悉Console
类和readline to Java端口。
然后,我没有指定编码而是创建InputStreamReader
,而是在更高层次抽象:
interface CommandLineSource {
String readLine() throws IOException;
}
然后你可以创建一个由FileDescriptor.STDIN
支持的,另一个由你喜欢的,以便你可以自动输入测试。