Shuzheng
Shuzheng

Reputation: 13948

Java Scanner.hasNextLine() doesn't detect an empty line?

Suppose I've the following file

Hej Hej Hej
A A A A

with a line break after the line with A's.

My problem is that the code

while (in.hasNextLine()) {
    String line = in.nextLine();
    if (in.hasNextLine()) {
        out.println(line);
    }
    else {
        out.print(line);
    }
}

doesn't detect this extra line in in.hasNextLine(), so I miss the line break in the ouput file (I'm doing a file concatenation program). What could the problem be?

Upvotes: 0

Views: 1998

Answers (2)

Klitos Kyriacou
Klitos Kyriacou

Reputation: 11641

Scanner.getLine() reads all characters on the currently line, including the line terminator (if there is one), and then it discards the line terminator. Using this method, there is no way of knowing if the file ends with or without a line terminator.

If you are writing a file concatenation program, why do you want to read line-by-line? Doing so could cause loss of data; for example, your output file would use the platform-default line terminator (e.g. "\r\n" or "\n") irrespective of which line terminator your input files were using.

It would make more sense to read and write the files as a stream of bytes, e.g. using InputStream.read(byte[]). Even better, use java.nio.file.Files.copy(Path source, OutputStream out) which was newly introduced in Java 7 and does all the hard work for you.

One word of caution, however, is that if the files you want to concatenate are text files with different character encodings, you'll want to convert them to all use the same encoding in the output file. In that case, use a FileReader and a Writer instead.

Upvotes: 0

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62864

Your invoking .hasNextLine() twice, while you're reading the "next line" just once.

Your code should rather be:

while (in.hasNextLine()) {
    String line = in.nextLine();        
    out.println(line);            
}

Or, if you want to check within the loop again for next line existence, you should do this (which I find not clean enough, because it does exactly the same as the snippet above):

while (in.hasNextLine()) {
    String line = in.nextLine();
    if (in.hasNextLine()) {
        String nextLine = in.nextLine();
        out.println(line);
    } else {
        out.print(line);
    }
}

Upvotes: 5

Related Questions