2

我编写了一个 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,则每行一输入就会被读取。

所以,我的问题分为两部分:

  1. 这种差异从何而来?
  2. 如何解决?

请注意,从GuiIn每个字节的裸字节读取可以正常工作,并且我已经尝试过减小BufferedReader缓冲区大小等技巧。

我也事先在网上搜索过:这不是关于创建模拟对象;并且ByteArrayInputStream也不是一个选项:它不支持追加。

4

1 回答 1

2

您的问题的一个来源可能是InputStreamReader可能坚持进一步阅读,以便可以确定它使用的byte->char解码器(并且对它不透明)有足够的字节来产生完整的char同时System.in可能对默认编码有足够的了解提供足够的字节。

在开始使用 Java 进行交互式控制台之前,您应该熟悉Console类和Java端口的readline 。

然后,我不会在不指定编码的情况下创建InputStreamReaders,而是在更高级别进行抽象:

interface CommandLineSource {
  String readLine() throws IOException;
}

然后您可以创建一个由FileDescriptor.STDIN.

于 2012-12-05T19:35:05.963 回答