こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

BufferedReaderでのエラー

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)

投稿日時 - 2009-05-16 15:29:23

QNo.4963509

困ってます

質問者が選んだベストアンサー

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();
}
ご参考まで。

投稿日時 - 2009-05-16 16:46:45

お礼

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

投稿日時 - 2009-05-16 17:07:56

ANo.2

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

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

投稿日時 - 2009-05-16 15:51:58

お礼

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

投稿日時 - 2009-05-16 17:08:40