Java 使用 BufferedReader 读取所有行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28977308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:07:20  来源:igfitidea点击:

Read all lines with BufferedReader

javabufferedreaderinfinite-loopinputstreamreader

提问by deadpixels

I want to type a multiple line text into the console using a BufferedReader and when I hit "Enter" to find the sum of the length of the whole text. The problem is that it seems I'm getting into an infinite loop and when I press "Enter" the program does not come to an end. My code is below:

我想使用 BufferedReader 在控制台中输入多行文本,当我点击“Enter”键来查找整个文本长度的总和时。问题是我似乎进入了一个无限循环,当我按“Enter”时,程序并没有结束。我的代码如下:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();

    while (line!=null){
        length = length + line.length();
        line= buffer.readLine();
    }

Could you please tell me what I'm doing wrong?

你能告诉我我做错了什么吗?

采纳答案by Elliott Frisch

The idiomatic way to read all of the lines is while ((line = buffer.readLine()) != null). Also, I would suggest a try-with-resourcesstatement. Something like

阅读所有行的惯用方法是while ((line = buffer.readLine()) != null). 另外,我会建议一个try-with-resources声明。就像是

try (InputStreamReader instream = new InputStreamReader(System.in);
        BufferedReader buffer = new BufferedReader(instream)) {
    long length = 0;
    String line;
    while ((line = buffer.readLine()) != null) {
        length += line.length();
    }
    System.out.println("Read length: " + length);
} catch (Exception e) {
    e.printStackTrace();
}

If you want to end the loop when you receive an empty line, add a test for that in the whileloop

如果你想,当你收到一个空行来结束循环,在添加一个测试为while循环

while ((line = buffer.readLine()) != null) {
    if (line.isEmpty()) {
        break;
    }
    length += line.length();
}

JLS-14.15. The breakStatementsays

JLS-14.15。该break声明说:

A breakstatement transfers control out of an enclosing statement.

一个break语句将控制一个封闭的声明出来。

回答by dbank

linewill not be null when you press enter; it will be an emptystring.

line按回车键时不会为空;它将是一个字符串。

Take note of what the BufferedReaderJavaDocsays about readLine():

请注意BufferedReaderJavaDoc所说的内容readLine()

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

读取一行文本。一行被视为以换行符 ('\n')、回车符 ('\r') 或回车符后紧跟换行符中的任何一个结束。

And readLine()returns:

readLine()返回:

A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached

包含行内容的字符串,不包括任何行终止字符,如果已到达流的末尾,则为 null

So when you press [Enter], you are giving the BufferedReadera new line containing only \n, \r, or \r\n. This means that readLine()will return an empty string.

所以,当你按[Enter],你给了BufferedReader只包含一个新的生产线\n\r\r\n。这意味着readLine()将返回一个空字符串。

So try something like this instead:

所以尝试这样的事情:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while( (line != null) && (!line.isEmpty()) ){
    length = length + line.length();
    line = buffer.readLine();
}

回答by Foon

Snarky answer: what you're doing wrong is only creating 2 objects in Java to do something... if you search, you can probably find a few more classes that extend BufferedReader or ExtendedBufferReader etc., and then it can be real Enterprise Java.

尖锐的回答:你做错的只是在 Java 中创建 2 个对象来做某事......如果你搜索,你可能会找到更多扩展 BufferedReader 或 ExtendedBufferReader 等的类,然后它可以是真正的 Enterprise Java .

Now that i've gotten that out of my system: more useful answer. System.in is closed when you input EOF, which is Control-D under Linux and I think MacOS, and I thinkControl-Z plus enter under Windows. If you want to check for enter (or more specifically, two enters... one to finish the last line and one to indicate that you're done, which is essentially how http handles determining when the http headers are finished and it's time for the http body, then @dbank 's solution should be a viable option with a minor fix I'm going to try to make to move the ! inside the while predicate instead of !while.

现在我已经从我的系统中得到了:更有用的答案。当你输入EOF,这是Linux下控制-d,我认为MacOS的System.in是封闭的,而且我认为控制-Z,以及Windows下进入。如果您想检查输入(或者更具体地说,两次输入...一次完成最后一行,另一次表示您已完成,这基本上是 http 处理确定 http 标头何时完成以及是时候http 正文,那么@dbank 的解决方案应该是一个可行的选择,我将尝试将!

(Edit #2: realized readLine strips the newline, so an empty line would "" instead of the newline, so now my code devolves to another answer with the EOF bit as an answer instead of comment)

(编辑#2:实现 readLine 去除换行符,因此空行将“”而不是换行符,所以现在我的代码转移到另一个答案,使用 EOF 位作为答案而不是注释)

Edit... that's weird, @dbank had answered while I was typing my answer, and I would have stopped had I not though mentioning the EOF alternative. To repeat his code from memory with the edit I was going to make:

编辑...这很奇怪,@dbank 在我输入答案时已经回答了,如果我没有提到 EOF 替代方案,我就会停下来。用我要进行的编辑从记忆中重复他的代码:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

    line= buffer.readLine();
    while (line != null && !line.equals("")){
        length = length + line.length();
        line= buffer.readLine();
    }

回答by Stephen Buttolph

When you only press Enter the return from buffer.readLine();isn't null it is an empty String.

当您只按 Enter 时, return from buffer.readLine();is not null 它是一个空字符串。

Therefore you should change line != nullto !line.equals("")(You could also change it to line.length() > 0)

因此,您应该更改line != null!line.equals("")(您也可以将其更改为line.length() > 0

Now your code will look something like this:

现在你的代码看起来像这样:

InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(instream);

line = buffer.readLine();

while (!line.equals("")){
    length = length + line.length();
    line = buffer.readLine();
}

This should solve your problem. Hope this helped! :)

这应该可以解决您的问题。希望这有帮助!:)

回答by Grzegorz Gajos

Since Java 8 you can use BufferedReader#linesmethod directly on buffered reader.

从 Java 8 开始,您可以BufferedReader#lines直接在缓冲读取器上使用方法。

    try (InputStreamReader in = new InputStreamReader(System.in);
         BufferedReader buffer = new BufferedReader(in)) {
        final int length = buffer.lines().mapToInt(String::length).sum();
        System.out.println("Read length: " + length);
    } catch (Exception e) {
        e.printStackTrace();
    }

回答by Russel Yang

One line of code using Java 8:

一行代码使用 Java 8:

line =  buffer.lines().collect(Collectors.joining());

回答by Snow Bases

Put every lines into String[] array. and second method get the number of lines contains in text file. I hope this might be useful to anyone..

将每一行放入 String[] 数组。第二种方法获取文本文件中包含的行数。我希望这可能对任何人有用..

public static void main(String... args) throws IOException {
    String[] data = getLines();
    for(String v : data) {
        out.println(v);
    }
}

public static String[] getLines() throws IOException {
    BufferedReader bufferReader = new BufferedReader(new FileReader("C:\testing.txt"));
    String line = bufferReader.readLine(); 
    String[] data = new String[getLinesLength()];
    int i = 0;
    while(line != null) {
        data[i] = line; 
        line = bufferReader.readLine();
        i++;
    }
    bufferReader.close();
    return data;
}

public static int getLinesLength() throws IOException {
    BufferedReader bufferReader = new BufferedReader(new FileReader("C:\testing.txt"));
    String line = bufferReader.readLine(); 
    int size = 0;
    while(line != null) {
        size += 1;
        line = bufferReader.readLine();
    }
    bufferReader.close();
    return size;
}