FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]
A DESCRIPTION OF THE PROBLEM :
If a text file ends with one or more empty lines, Files.readAllLines(Path, Charset) does not include the last line in its returned list.
For example, if new String(Files.readAllBytes(path), cs) returns "kekeke\r\n" as expected, Files.readAllLines(path, cs) returns a list with the single member "kekeke".
If the former returns "kekeke\r\n\r\n\r\n", the latter returns the list ["kekeke", "", ""], and so on.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code I included in the report (after changing the value of pathString to something appropriate, if necessary).
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the file C:\newtestfolderrsdfgjsoe\textfile.txt to be created (or overwritten) with the text 'kekeke' on the first line followed by an empty line (as well as the parent directory to be created if necessary).
I expected the output to be:
[kekeke, ]
kekeke
true
true
ACTUAL -
The file C:\newtestfolderrsdfgjsoe\textfile.txt was created with the text 'kekeke' on the first line followed by an empty line.
The output was:
[kekeke]
kekeke
true
true
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
String pathString = "C:\\newtestfolderrsdfgjsoe\\textfile.txt";
Path path = Paths.get(pathString);
Files.createDirectories(path.getParent());
String text = "kekeke";
try (PrintWriter writer = new PrintWriter(path.toFile(), "UTF-8")) {
writer.println(text);
}
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
String fileAsString = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
System.out.println(lines);
System.out.println(fileAsString);
System.out.println(new ArrayList<String>(lines).equals(new ArrayList<String>(Arrays.asList(text))));
System.out.println(fileAsString.equals(text + "\r\n"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use Files.readAllBytes() and split by line break characters.
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]
A DESCRIPTION OF THE PROBLEM :
If a text file ends with one or more empty lines, Files.readAllLines(Path, Charset) does not include the last line in its returned list.
For example, if new String(Files.readAllBytes(path), cs) returns "kekeke\r\n" as expected, Files.readAllLines(path, cs) returns a list with the single member "kekeke".
If the former returns "kekeke\r\n\r\n\r\n", the latter returns the list ["kekeke", "", ""], and so on.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the source code I included in the report (after changing the value of pathString to something appropriate, if necessary).
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the file C:\newtestfolderrsdfgjsoe\textfile.txt to be created (or overwritten) with the text 'kekeke' on the first line followed by an empty line (as well as the parent directory to be created if necessary).
I expected the output to be:
[kekeke, ]
kekeke
true
true
ACTUAL -
The file C:\newtestfolderrsdfgjsoe\textfile.txt was created with the text 'kekeke' on the first line followed by an empty line.
The output was:
[kekeke]
kekeke
true
true
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
String pathString = "C:\\newtestfolderrsdfgjsoe\\textfile.txt";
Path path = Paths.get(pathString);
Files.createDirectories(path.getParent());
String text = "kekeke";
try (PrintWriter writer = new PrintWriter(path.toFile(), "UTF-8")) {
writer.println(text);
}
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
String fileAsString = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
System.out.println(lines);
System.out.println(fileAsString);
System.out.println(new ArrayList<String>(lines).equals(new ArrayList<String>(Arrays.asList(text))));
System.out.println(fileAsString.equals(text + "\r\n"));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Use Files.readAllBytes() and split by line break characters.