使用 BufferedReader 读取所有行

问题描述 投票:0回答:8

我想使用 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();
    }

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

java bufferedreader infinite-loop inputstreamreader
8个回答
110
投票

更新 Java 16:

line =  buffer.lines().toList();

使用 Java 8 的一行代码:

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

40
投票

阅读所有行的惯用方法是

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

如果您想在收到空行时结束循环,请在

while
循环中添加一个测试

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

JLS-14.15。

break
声明

break
语句将控制权移出封闭语句。


5
投票
当你按回车时

line
不会为空;它将是一个字符串。

注意

BufferedReader
JavaDoc 关于
readLine()
的说法:

读取一行文本。一行被认为由任何一个换行符 (' '), 回车符 (' '),或回车后紧跟换行符。

并且

readLine()
返回:

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

因此,当您按 [Enter] 时,您将为

BufferedReader
提供一个仅包含
\n
\r
\r\n
的新行。这意味着
readLine()
将返回一个空字符串。

所以尝试这样的事情:

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

4
投票

当您仅按 Enter 键时,

buffer.readLine();
的返回值不为 null,而是一个空字符串。

因此您应该将

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

现在您的代码将如下所示:

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

line = buffer.readLine();

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

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


2
投票

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

0
投票

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

现在我已经从我的系统中得到了这个:更有用的答案。当你输入EOF时System.in就关闭了,在Linux和我认为MacOS下是Control-D,在Windows下我认为Control-Z加回车。如果您想检查是否输入(或者更具体地说,两个输入...一个用于完成最后一行,另一个用于指示您已完成,这本质上是 http 处理确定 http 标头何时完成以及何时完成的方式http 主体,那么 @dbank 的解决方案应该是一个可行的选择,只需进行一个小修复,我将尝试将 ! 移动到 while 谓词而不是 !while 中。

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

编辑...这很奇怪,@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();
    }

0
投票

将每一行放入 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;
}

0
投票

@Russel Yang 的好例子(https://stackoverflow.com/a/40412945/11079418)。

使用此代码,在每行后面添加一个新行字符。

String lines = bufferedReader.lines().map(line -> line + "\n").collect(Collectors.joining());
© www.soinside.com 2019 - 2024. All rights reserved.