Java-如何使用扫描仪获取最后一行?

Java-如何使用扫描仪获取最后一行?,java,java.util.scanner,Java,Java.util.scanner,lineList是一个ArrayList。代码可以很好地读取所有内容,但它不会抓住最后一行。文本文件中的最后两行结尾如下: while( inStream.hasNextLine() ) { ... lineList.add( inStream.nextLine() ); } ... 这就是整个方法。有什么问题吗 编辑:更多信息 public void readLi

lineList是一个ArrayList。代码可以很好地读取所有内容,但它不会抓住最后一行。文本文件中的最后两行结尾如下:

        while( inStream.hasNextLine() )
        {
                ...

                lineList.add( inStream.nextLine() );
        }
        ...
这就是整个方法。有什么问题吗

编辑:更多信息

public void readLines()
{
    lineList = new ArrayList();

    try
    {
        inStream = new Scanner( new File( fileName ) );
    }
    catch( FileNotFoundException e )
    {
        System.out.println( "Error opening the file. Try again." );
    }


    if ( inStream != null )
    {
        while( inStream.hasNextLine() )
        {
            ++originalLines;

            lineList.add( inStream.nextLine() );
        }
        inStream.close();
    }
}

它不会拾取一个空字符串,但会拾取一个空白“

这段代码对我来说很好——您确定在结尾处有一个空行(如,文件以两个换行结束,而不仅仅是一个换行)?

nextLine()
返回最后一行很好,即使它是空的。我怀疑你的问题在别处

public static void main(String[] args)
{
    Scanner inStream = null;
    String test = "";

    inStream = new Scanner( test );

    while( inStream.hasNextLine() )
    {
        System.out.println( inStream.nextLine() );
    }
}

它不会拾取空字符串

这是设计的正确行为。如果输入是空字符串,您不能期望
扫描仪
hasNextLine()
并在
nextLine()
上返回空字符串,特别是因为这不会使
扫描仪
超过任何字符


如果你仔细想想,如果你期望一个
扫描器在一个空字符串上说
hasNextLine()
,然后在
nextLine()
上返回一个空字符串,那么这将导致一个无限循环:它将始终
hasNextLine()
并且它将永远在
nextLine()
上返回一个空字符串。这种行为显然是不切实际的。

扫描器不会拾取空字符串。没有任何东西可以标记。Scanner是一个标记器,根据Java6Javadoc,默认使用Character.isWhitespace。每次遇到令牌时,都会将其作为字符串返回,但不包括令牌。如果最后一项是令牌,则将删除该项,并且不添加新行。ArrayList中可能会出现空字符串,但它只是一个空字符串,因为标记已被删除。没有数据和令牌,扫描器看不到行。您在编辑器中看到的不是一个空行。光标位于键入时将添加字符的位置。如果你不键入任何内容,那里就没有实际的行。

我想指出,两者都有

String multilinetext =
    "Line1\n" +
    "Line2\n" +
    "\n" +
    "Line4\n" +
    "\n";
Scanner sc = new Scanner(multilinetext);
while (sc.hasNextLine()) {
    System.out.println("[" + sc.nextLine() + "]");
}
/* prints 
[Line1]
[Line2]
[]
[Line4]
[]
*/

使用@Polygene代码返回完全相同的结果,即:

String multilinetext =
    "Line1\n" +
    "Line2\n" +
    "\n" +
    "Line4";
因为扫描器不会返回最后的“换行”字符


因此,如果你想得到最后一行“空”,这不是正确的解决方案,你应该读取每个字节。

终于找到了获得所有行的方法!代码如下:

[Line1]
[Line2]
[]
[Line4]
不客气。 (已测试JDK 1.8、JDK 11.0.2、JDK 12.0.2)

更新:2019-09-23
我发现即使是第一条线也可以是一项任务!我发布了更新后的代码,因此符合“每一行”的要求。

是的。嗯,我不知道你是否可以称之为空行。它更像是一个空字符串?里面什么都没有。例如,如果在最后一行中,您将光标设置为它,然后按向右箭头键,它将不会移动。我已将整个方法添加到我的OP中。您可以检查它吗?方法对我来说很好。使用
wc-l
或十六进制编辑器等查看文件真正包含的内容。执行“如果我按向右箭头键,它不会移动”测试是无用的,因为这取决于文本编辑器的行为,而不是实际文件包含的内容。谢谢。我猜它不是一个分隔符,而是一个空字符串。如果我的猜测是正确的,我将如何拾取空字符串?请参阅上面添加的代码。谢谢。这是有道理的。但是,有没有办法检索到这个空白呢?啊,正如我在最近的回答中提到的,我认为如果你在编辑器中看到一行额外的内容,那么它仅仅是指向新文本将出现的地方的光标。如果您真的想要它,请接受Polygene的建议(进一步)并添加lineList;外面一会儿。谢谢你。这是有道理的。我想我可以把它删掉,所以原来的帖子显然是为了把文件输入流处理成一个列表。我承认用扫描仪来做这件事并不理想;我的解决方案基于找到一个解决方案,通常使用Scanner类处理输入流。
String multilinetext =
    "Line1\n" +
    "Line2\n" +
    "\n" +
    "Line4";
[Line1]
[Line2]
[]
[Line4]
public static void main(String[] args) {
    String multiLineText = "Line1\n" +
        "Line2\n" +
        "\n" +
        "Line4\n" +
        "\n" +
        "";
    Scanner scanner = new Scanner(multiLineText).useDelimiter("\r?\n");
    String line = firstLine(scanner);
    System.out.println("[" + line + "]");
    while (hasNextLine(scanner)) {
        line = nextLine(scanner);
        System.out.println("[" + line + "]");
    }
    /* prints ALL six lines */
    // [Line1]
    // [Line2]
    // []
    // [Line4]
    // []
    // []
    scanner.close();
}

private static String firstLine(Scanner scanner) {
    // Check for empty first line.
    scanner.useDelimiter("");
    if (scanner.hasNext("\n")) {
        scanner.useDelimiter("\r?\n");
        return "";
    }

    // Check for empty input.
    scanner.useDelimiter("\r?\n");
    if (scanner.hasNext()) {
        return scanner.next();
    }

    return "";
}

private static boolean hasNextLine(Scanner scanner) {
    return scanner.hasNext() || scanner.hasNextLine();
}

private static String nextLine(Scanner scanner) {
    if (scanner.hasNext()) {
        return scanner.next();
    }
    return scanner.nextLine();
}