On reading and rereading you code, I think that it might actually add a newline at the start of the file, and/or remove the last newline if the original file's last character is a newline. It is hard to tell, because your snippet is not a minimal reproducible example.
According to the javadoc for Scanner.nextLine
:
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
When I look at the Scanner
code, the actual implemented behavior is to match either up to and including the next line separator OR up to the end of the input. So if the last line of the input doesn't end with a line separator, it will still be returned by nextLine()
.
Anyway ...
Your code has a number of problems:
It adds an extra newline if the last line doesn't has a line separator; see above.
It changes all of the line separators to newlines. (Which is fine in some situations, but not in others.)
It buffers the entire file in memory. (That's fine if the file is small, but not if the file is tens of megabytes or more.)
The methodology for building the in-memory file copy is inefficient. Each time you concatenate the strings in
fullData = fullData + "\n" + data;
you are copying all of the data read so far to a new string. The result is O(N^2)
data copying to read an N
character file.
It is more efficient to use a StringBuilder
to concatenate multiple strings, but in the case where you are reading an entire file, there are better solutions. See How do I create a Java string from the contents of a file?.
Note that to solve the problems with line separators, you need a solution that doesn't involve Scanner.nextLine
or BufferedReader.readLine
because both of these lose the details of the actual line separators used.