- ベストアンサー
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)
- みんなの回答 (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(); } ご参考まで。
その他の回答 (1)
- Yanch
- ベストアンサー率50% (114/225)
標準入力の「System.in」をcloseしちゃってたりしませんか?
お礼
しているつもりはありませんでしたが, br.closeによって間接的にしちゃってました・・・.
お礼
System.inがstaticのことや,br.closeで一緒にリソース開放されるとは 知りませんでした.ご指摘,手直しありがとうございました.