0

InputStreamスロー ストリームをシミュレートするモックを次に示します。

class SlowInputStream extends InputStream{
    private String internal = "5 6\nNext Line\n";
    private int position = 0;

    @Override
    public int available(){
        if(position==internal.length()) return 0;
        else return 1;
    }

    @Override
    public int read() throws IOException {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new IOException("Sleep Interrupted");
        }
        if(position==internal.length()) return -1;
        return internal.charAt(position++);

    }

}

そして、ここにテストコードがあります:

    Scanner s = new Scanner(new SlowInputStream());

    int i=s.nextInt();
    System.out.println("i="+i);
    int j=s.nextInt();
    System.out.println("j="+j);
    s.nextLine();
    String line = s.nextLine();
    System.out.println("line="+line);

    s.close();

上記のコードの動作は、しばらく停止して 3 行を出力することです。同じことを出力するが、待ち時間を行間で分割できるコードはどれですか?

4

2 に答える 2

0

read(byte[], int, int) もオーバーライドする必要があります。FilterInoutStream を拡張したほうがよいでしょう。それが目的です。

于 2013-01-08T08:46:18.300 に答える
-1

Scannerが から作成された場合、InputStreamパフォーマンスを向上させるために、毎回特定の量のデータを読み取ろうとします。私のマシンでは、量は 4096 バイトです。これが、この例ですべての結果を同時に出力するまで常に待機し続ける理由です。

このキャッシュ メカニズムをバイパスするReadableには、生のストリームではなくインターフェイスを使用する必要があります。これを実行できる既知の実装がないため、独自に実装する必要があります。(誰かがそのようなことを知っているなら、私に知らせてください)したがって、次のコードは仕事をすることができます:

Scanner s = new Scanner(new Readable(){

    private InputStream is = new SlowInputStream();

    public int read(CharBuffer arg0) throws IOException {
        int i = is.read();
        if(i>=0){
            arg0.append((char)i);
            return 1;
        } else return -1;
    }

});

int i=s.nextInt();
System.out.println("i="+i);
int j=s.nextInt();
System.out.println("j="+j);
s.nextLine();
String line = s.nextLine();
System.out.println("line="+line);

s.close();

編集:上記の解決策にはいくつかの欠点があります。まず、内部入力ストリームを閉じないため、リークが発生します。次に、文字セットが 1 バイトであるかどうかによって異なります。複数バイトの文字セット (つまり、UTF-8) では機能しません。これらの問題を解決するには、ReadableByteChannel代わりにa を使用できます。

Scanner s = new Scanner(new ReadableByteChannel(){

    private InputStream is = new SlowInputStream();
    boolean isopen = true;

    public int read(ByteBuffer arg0) throws IOException {
        int i = is.read();
        if(i>=0){
            arg0.put((byte)i);
            return 1;
        } else return -1;
    }

    public void close() throws IOException {
        isopen=false;
        is.close();
    }

    public boolean isOpen() {
        return isopen;
    }

});

編集:コメントありがとうございます。テキストのエラーを修正し、この問題についてより適切に説明しました。

于 2012-11-29T01:54:53.203 に答える