私のJavaプログラムは標準入力をリッスンしています:
InputStreamReader isReader = new InputStreamReader(System.in);
BufferedReader bufReader = new BufferedReader(isReader);
while(true){
try {
String inputStr = null;
if((inputStr=bufReader.readLine()) != null) {
...
}
else {
System.out.println("inputStr is null");
}
}
catch (Exception e) {
...
}
}
ここで、bashからこのプログラムへの入力をパイプ処理したいと思います。私は以下を試しました:
echo "hi" | Java -classpath ../src test.TestProgram
しかし、それはただ印刷しているだけですinputStr is null
無限の時間。私は何が間違っているのですか?
編集1:より多くのコード/コンテキストを含むように質問を更新しました。
編集2:
このOPと同じ問題が発生しているようです: Javaでのコマンドラインパイプ入力
テスト用に入力をパイプインできるようにプログラムを修正するにはどうすればよいですか?プログラムを通常実行すると、ユーザーは標準入力にも入力を入力できますか?
修正しました。入力のパイプ処理が完了した後、readLine()
がnull
を返し続けたため、無限ループがループし続けました。
修正は、readLine()
がnullを返したときに無限ループから抜け出すことです。
while(true)
があるので、無限ループが得られます。
ループのどこかにbreak
を追加することは、それを修正する1つの方法です。しかし、読者はループが終了するかどうか、いつ終了するかを確認するためにループを探し回る必要があるため、これは良いスタイルではありません。
while
ステートメントに終了条件が何であるかを明確に示すようにすることをお勧めします。
String inputStr = "";
while(inputStr != null) {
inputStr=bufReader.readLine();
if(inputStr != null) {
...
} else {
System.out.println("inputStr is null");
}
}
私はスリムの答えが好きですが、私はそれを少し異なって扱う傾向があります。これは、テキストのストリームを1行ずつ読み取るために使用する基本的なテンプレートです。
try {
// Wrap the System.in inside BufferedReader
// But do not close it in a finally block, as we
// did no open System.in; enforcing the rule that
// he who opens it, closes it; leave the closing to the OS.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
// TODO: Handle input line
}
// Null was received, so loop was aborted.
} catch (IOException e) {
// TODO: Add error handler
}
ファイルを読んでいる場合は、少し変更して、このようにファイルを閉じます
try {
File file = new File("some_file.txt");
// Wrap the System.in inside BufferedReader
// But do not close it in a finally block, as we
// did no open System.in; enforcing the rule that
// he who opens it, closes it; leaves the closing to the OS.
BufferedReader in = new BufferedReader(new FileReader(file));
try {
String line;
while ((line = in.readLine()) != null) {
// TODO: Handle input line
}
// Null was received, so loop was aborted.
} finally {
try {
in.close();
} catch (IOException e) {
}
}
} catch (IOException e) {
// TODO: Add error handler
}
私は何が間違っているのですか?
スニペットがそのように動作する理由はわかりません。問題はあなたが私たちに示していない何かにあると思います...
たとえば、どのバージョンのecho
を使用していますか?ビルトインシェル? '/ bin'の標準のもの?あなたの検索パスにファンキーなものがありますか?
いくつかの簡単な実験を試して、問題がシェル/コマンドレベルにあるのか、Javaアプリケーション;例:.
$ echo hi > tmp
$ cat tmp
$ Java -classpath ../src test.TestProgram < tmp
$ cat tmp | Java -classpath ../src test.TestProgram
エトセトラ。
これらの実験のいずれも手がかりが得られない場合は、問題を示す小さなプログラムの実際のJavaソースコードを投稿してください。
(そして@trashgodが正しく指摘しているように、ビルド手順に「太っている」と思われ、ソースコードと一致しないバージョンのプログラムを実行している可能性があります。)
名前付きパイプ(fifos)を使用して、制御ターミナルからの両方の通常の入力を許可することを検討できます/dev/tty
(または/dev/stdin
)および入力FIFOを介したパイプ入力。