5

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

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();
    }
}

それについて Javadoc を読むことから、次のreadLine()ように述べています。

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

戻り値:String行終了文字を含まない、行の内容を含む A、またはストリームの終わりに達した場合は null

例外: IOException- I/O エラーが発生した場合

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

4

3 に答える 3

10

これについての私の理解では、readLine は、'\r' のような行末以外の入力が初めて入力されなかったときに null を返す必要があります。

それは正しくありません。ストリームの終わりに達した場合にreadLine返されます。nullこれは、たとえば、ファイルを読み取っていてファイルが終了した場合、またはソケットから読み取っていてソケットが閉じた場合です。

ただし、単にコンソール入力を読み取るだけの場合は、キーボードのリターン キーを押してもストリームの終了にはなりません。返されるのは単なる文字です(\nまたは\r\nOSによって異なります)。

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

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

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

java -cp . Echo < test.txt
于 2008-08-24T13:41:06.963 に答える
3

入力がないことは、ストリームの最後と同じではありません。Ctrl通常、コンソールで+を押すと、ストリームの終了をシミュレートできますD(一部のシステムでは代わりにCtrl+が使用されZます)。しかし、これはあなたが望むものではないと思うので、null 文字列に加えて空の文字列をより適切にテストしてください。

于 2008-08-24T13:32:37.170 に答える
1

一般的な :) アクション用の優れた API を持つ、すばらしいapache commons langライブラリがあります。静的に import StringUtils を使用し、そのメソッド isNotEmpty(String ) を使用して取得できます。

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

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

于 2008-08-30T22:43:46.627 に答える