0

以下のコードを使用して、コマンドラインで stdin から sql ステートメントを読み取ります。

    BufferedReader in = null;
    StringBuilder sb = new StringBuilder();
    String line = null;
    try {
        in = new BufferedReader(new InputStreamReader(System.in));
        while((line = in.readLine()) != null) {
            sb.append(line);
        }
    } finally {
        if (in!=null) in.close();
    }

私の問題は、アプリケーションが標準入力からのデータを使用して実行する必要がある場合と、そうでない場合があることです (パイプ入力なし)。上記のコードに入力がない場合、in.readLine()ブロックします。何もパイプされていない場合でも実行できるように、このコードを書き直す方法はありますか?

更新: アプリケーションは、キーボードからではなく、コマンド ラインからパイプされたデータを期待するように設計されています。

4

5 に答える 5

2

最終的に別の入力行を取得するかどうかを確認する方法はないと思います。ユーザーが入力ストリームを閉じると(たとえば、端末に^ Dを使用して)、現在のコードは終了することに注意してください。

BufferedReader.ready()ストリームにデータがあるかどうかを確認します。TJが述べたように、あなたは運が悪く、実際にデータを受け取る直前にデータを要求するかもしれません。そしてあなたが彼らの質問に答えなかったのであなたのユーザーは悲しむでしょう。

Scanner.hasNextLine()はブロッキング操作なので、おそらくあなたが探しているものではありません。

たとえば、コマンドライン引数を使用して、System.inから読み取るかどうかをユーザーに指定させることができます。

于 2012-04-25T16:43:47.963 に答える
2

を使用readyして、ストリームにデータの準備ができているかどうかをテストできます。readyが返された場合false、ストリームを呼び出したときにデータの準備ができていませんでした (1 マイクロ秒後にデータを受信した可能性があります)。呼び出しreadyて が返された場合、ブロックせずにtrue呼び出すことができることがわかります。(もちろん、ブロックせずreadにコールすることはできません。)readLine

于 2012-04-25T16:29:44.320 に答える
1

オプションで stdin からの読み取りをサポートする Unix ユーティリティは、通常、コマンド ラインに基づいて何をすべきかを判断します。たとえばcat、コマンドラインでファイルが指定されていない場合、stdin から読み取ります。これらの行に沿って何かを行うことができます-コマンドラインフラグまたはオプション、またはプログラムが標準入力から何かを読み取ろうとするかどうかを示す何かを追加します。

もう 1 つの方法は、プログラムに読み取らせたい入力がない場合に、/dev/null から入力をリダイレクトすることです。この場合、stdin から読み取り、すぐにファイルの終わりを示すことができます。Windows に相当するのは、からリダイレクトすることNULです。

ブロックせずに stdin から読み取ることができるかどうかを検出するプログラムが本当に必要な場合は、 を参照してInputStream.available()ください。しかし、誰かがプログラムの入力を入力する (または端末ウィンドウにコピーして貼り付けるなど) ことをサポートしたい場合は、ユーザーが実際に何かを入力するまで、InputStream は入力を使用可能として表示しません。

于 2012-04-25T17:02:24.807 に答える
0

/proc/self/fd/0UNIXでは、ファイル、パイプ、またはコンソールのいずれを指しているかを確認できます。

$ ls -l /proc/self/fd/0
lrwx------ 1 peter peter 64 Apr 25 18:12 /proc/self/fd/0 -> /dev/pts/21
$ ls -l /proc/self/fd/0 < /dev/null
lr-x------ 1 peter peter 64 Apr 25 18:13 /proc/self/fd/0 -> /dev/null
$ echo Hello World | ls -l /proc/self/fd/0 
lr-x------ 1 peter peter 64 Apr 25 18:13 /proc/self/fd/0 -> pipe:[139250355]

これにより、入力がファイルであるか、パイプされているか、またはターミナルであるかがわかります。

于 2012-04-25T17:16:15.953 に答える
0

パイプ入力がない場合のプログラムの実行方法によって異なります。通常、プログラムにはオープンな stdin があり、できることはタイマーを設定し、入力があるまで一定時間待機し、タイマーが入力なしで期限切れになった場合は何もないと想定することだけです。別の方法として、stdin を閉じた状態でプログラムを実行するように調整することもできます。この場合、読み込もうとすると EOF が返されます。

UNIX (Mac OS を含む) で stdin を閉じるには、bash スクリプトを記述してプログラムを起動します。

#!/bin/bash

exec 0>&- # close stdin

java -jar yourProgram.jar # run your program

もちろん、とにかく bash コマンド ラインから起動する場合は、スクリプトは必要ありません。

prompt> java -jar yourProgram.jar 0>&-

しかし、プログラムが Java EE コンテナーで実行されている場合、起動前に stdin を閉じる方法がわかりません。おそらくできないでしょう。

于 2012-04-25T17:06:16.753 に答える