質問

以下のコードスニペットを使用していますが、理解しているとおりに機能していません。

public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    String line;
    try {
        line = br.readLine();
        while(line != null) {
            System.out.println(line);
            line = br.readLine();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

readLine()についてのJavadocを読むと:

テキスト行を読み取ります。行は、ラインフィード( \ n )、キャリッジリターン( \ r )、またはキャリッジリターンとそれに続くラインフィードのいずれかで終了すると見なされます。 。

返品: 行終了文字を含まない行のコンテンツを含む String 、またはストリームの終わりに達した場合はnull

スロー IOException -I / Oエラーが発生した場合

これを理解すると、 \ r のように、行終了以外の入力が初めて入力されたときに readLine はnullを返すはずです。ただし、このコードは無限にループするだけです。デバッグ後、終了文字が入力されたときにnullが返されるのではなく、実際には空の文字列("")が返されることがわかりました。これは私には意味がありません。正しく理解できないものは何ですか?

役に立ちましたか?

解決

  

これを理解したことから、readLineは、 '\ r'などの行終端以外の入力が初めて入力されたときにnullを返すはずです。

それは正しくありません。ストリームの最後に到達すると、 readLine null を返します。つまり、たとえば、ファイルを読み込んでいてファイルが終了した場合、またはソケットから読み込んでソケットがクラッシュした場合です。

ただし、単にコンソール入力を読んでいる場合、キーボードのリターンキーを押してもストリームの終わりにはなりません。返されるのは単なる文字です(ご使用のOSに応じて \ n または \ r \ n )。

したがって、空の文字列と行末の両方で改行する場合は、次のようにする必要があります。

while (line != null && !line.equals(""))

また、次のようにファイルを直接パイプすると、現在のプログラムは期待どおりに動作するはずです:

java -cp . Echo < test.txt

他のヒント

入力なしは、ストリームの終わりと同じではありません。通常、コンソールでストリームの終わりをシミュレートするには、 Ctrl + D を押します(一部のシステムでは Ctrl + Z <代わりに/ kbd>)。しかし、これはあなたが望んでいるものではないので、null文字列に加えて空の文字列をより良くテストします。

apache commons lang ライブラリには、common :)アクションに適したAPIがあります。 StringUtilsを静的にインポートし、そのメソッドisNotEmpty(String)を使用して以下を取得できます。

while(isNotEmpty(line)) {
    System.out.println(line);
    line = br.readLine();
}

いつか役に立つかもしれません:)このライブラリには他にも便利なクラスがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top