2

stdinから行を読み取り、各行の可能な補完を出力するJavaCLIプログラムを作成しました。私はそれに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、入力するとすぐに各行が読み込まれます。

したがって、私の質問は2つの部分に分かれています。

  1. この違いはどこから来るのですか?
  2. それを修正する方法は?

GuiIn1バイトあたりのベアバイトからの読み取りは正しく機能し、BufferedReaderバッファのサイズを小さくするなどのトリックをすでに試したことに注意してください。

また、事前にWebを検索しました。これは、モックオブジェクトを作成することではありません。ByteArrayInputStreamもオプションではありません。追加をサポートしていません。

4

1 に答える 1

2

問題の原因の1つは、使用する(そして不透明な)デコーダーがフルを生成するのに十分なバイトを持っていることInputStreamReaderを確認できるように、さらに先を読むことを主張する可能性がありbyteますが、デフォルトのエンコーディングについて十分に知っている可能性がありますちょうど十分なバイトを提供します。charcharSystem.in

Javaでインタラクティブなコンソール処理を開始する前に、ConsoleクラスとJavaポートへのリードラインについて理解しておく必要があります。

次に、InputStreamReaderエンコーディングを指定せずにsを作成する代わりに、より高いレベルで抽象化します。

interface CommandLineSource {
  String readLine() throws IOException;
}

次に、1つを作成しFileDescriptor.STDIN、もう1つを好きなように作成して、テスト用の入力を自動化できます。

于 2012-12-05T19:35:05.963 に答える