dポイントプレゼントキャンペーン実施中!

Javaプログラムを作成しています.
標準入力で入力された文字列を表示し,exitが入力されるまで繰り返すプログラムです.
エラーが出ますが,対策方法がわかりません.
ソースコード,実行結果,エラーは以下の通りです.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {

System.out.println("Program starts.");
while (true) {
String input = null;

input = getInputLine();
System.out.println("echo:" + input);

if (input.equals("exit")) {
break;
}
}
System.out.println("Program exits.");
}

private static String getInputLine() {
String input = null;
BufferedReader br = null;

try {
br = new BufferedReader(new InputStreamReader(System.in));
input = br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

return input;
}

}


Program starts.
test
echo:test
echo:null
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
at java.io.BufferedInputStream.read(BufferedInputStream.java:308)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at kadai1.Test.getInputLine(Test.java:34)
at kadai1.Test.main(Test.java:18)
Exception in thread "main" java.lang.NullPointerException
at kadai1.Test.main(Test.java:21)

A 回答 (2件)

getInputLineメソッド中に br.close(); という箇所があるのですが、マズイです。

実行開始して1回目の br.readLine(); は上手く実行されるのですが、その後、br.close(); にて標準入力である System.in までリソースを開放してしまいます。そして2回目に br.readLine() が実行されると、標準入力に関連した静的なSystem.inが既に開放されてしまっているので、例外処理となります。
標準入力はJavaアプリケーションを実行した時点で暗黙のうちに静的(static)に生成されます。mainメソッドと同様です。それをclose()にて開放してしまうのが原因です。BufferedReaderとInputStreamReaderは2回目以降もオブジェクトが作成されますが、System.inは一旦開放されるとダメっす。

手直ししましたので、ご参考まで。
--------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestBuf {

/**
* @param args
*/
static BufferedReader br = null;

public static void main(String[] args) {

br = new BufferedReader(new InputStreamReader(System.in));

System.out.println("Program starts.");
while (true) {
String input = null;

input = getInputLine();
System.out.println("echo:" + input);

if (input.equals("exit")) {
break;
}
}
System.out.println("Program exits.");

try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private static String getInputLine() {
String input = null;

try {
input = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}

return input;
}

}
--------------------------
余談ですが、JDK6(1.6)から、キーボード入力を簡単にできます。
private static String getInputLine() {
return System.console().readLine();
}
ご参考まで。
    • good
    • 0
この回答へのお礼

System.inがstaticのことや,br.closeで一緒にリソース開放されるとは
知りませんでした.ご指摘,手直しありがとうございました.

お礼日時:2009/05/16 17:07

標準入力の「System.in」をcloseしちゃってたりしませんか?

    • good
    • 1
この回答へのお礼

しているつもりはありませんでしたが,
br.closeによって間接的にしちゃってました・・・.

お礼日時:2009/05/16 17:08

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!