【问题标题】:BufferedReader not null yet .readLine() returning nullBufferedReader 还不是 null .readLine() 返回 null
【发布时间】:2016-01-03 06:01:06
【问题描述】:

我有一个奇怪的问题,我的代码看起来很好(至少对我来说),但在调试器上,实际结果总是错误的。

首先是代码:

private void updateRegistry( String filename ){
    BufferedReader database = Init.MANAGER.readFile( Path.getDB(), filename );

    REGISTRY.clear();

    long maxLines = database.lines().count();
    for (int i = 0; i < maxLines; i++) {
        try {
            String currentLine = database.readLine();
            Registry regAdd = new Entry( currentLine );
            REGISTRY.add( regAdd );
        } catch( Exception e ) {
            System.err.println( ERROR.getStackTrace( e ) );
        }
    }
}

因此,循环中的所有currentLine 变量总是返回null

作为REGISTRY 类上的常量,即LinkedList
ERROR 另一个常量来报告错误,这是不相关的。

我知道.readLine() 会在每个方法调用中读取一行,使每个调用都成为要读取的下一行。

另外,通过使用调试器,我可以确认BufferedReader 变量中的数据正在恢复。

然而.readLine() 方法返回空值。我不知道问题出在哪里。

我唯一的猜测是我曾经数过它们的.lines()。这会使流为空吗?如果这是问题所在,我该如何纠正它,因为我需要行数。

我做错了什么?我对此进行了一百次调试,但我所做的一切都没有给我数据。

编辑:

为了将来的参考,我使用了这个其他帖子的例子,我更喜欢这个例子而不是 while 循环。删除 .lines() 变量和循环后

private void updateRegistry( String filename ){
    BufferedReader database = Init.MANAGER.readFile( Path.getDB(), filename );

    REGISTRY.clear();

    try {
        for ( String currentLine = database.readLine(); currentLine != null; currentLine = database.readLine() ) {
            Registry regAdd = new Registry( currentLine );
            REGISTRY.add( regAdd );
        }
    } catch ( Exception e ){
        System.err.println( ERROR.getStackTrace( e ) );
    }
}

Post Link

感谢您的帮助,现在我可以更快地完成我的工作任务了! xD

作为,现在我最好的朋友Holger mentioned,将直接使用流循环,这样会更整洁。

database.lines().forEach(currentLine -&gt; REGISTRY.add(new Entry(currentLine)));

还有一个班轮!美丽的!在此之后将深入到流世界。

【问题讨论】:

    标签: java java-8 bufferedreader


    【解决方案1】:

    BufferedReader.lines():

    在终端流操作执行后,不能保证阅读器会处于读取下一个字符或行的特定位置。

    因此,在调用long maxLines = database.lines().count(); 之后,无法保证您之后可以从同一个阅读器中读取任何行。在典型实现中,此操作会消耗所有行。

    如果您无法重新获得等效阅读器,但确实需要事先计数,则唯一的选择是缓冲它们,例如将所有行收集到List 喜欢

    List<String> list=database.lines().collect(Collectors.toList());
    

    获取大小和内容。


    如果您不需要预先计数,可以将计数操作替换为您的实际操作:

    database.lines().forEach(currentLine -> REGISTRY.add(new Entry(currentLine));
    

    作为danmec has pointed out,即使没有流API,您也不需要事先计数,而您只想执行迭代。

    【讨论】:

    • 就像我认为的 .lines() 方法一样。谢谢你的匆忙。
    • 哦,我现在看到了编辑,对。这使它更清洁。非常感谢。
    【解决方案2】:

    BufferedReader.lines() 是 Java 8 中的一个新方法,我不太熟悉。但是,由于您只想依次处理每一行,因此您通常会使用以下内容:

    String currentLine = null;
    while ((currentLine = database.readLine()) != null) {
        // do processing
    }
    

    【讨论】:

    • 是的,我理解将分配作为条件的概念,这对我来说从未发生过。感谢您的快速回复。
    猜你喜欢
    • 1970-01-01
    • 2014-09-26
    • 2016-01-08
    • 1970-01-01
    • 2016-07-09
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多