The labs on this site need JavaScript to run. The same content is written out below.
Fundamentals › Java
What do you exchange when you write to and read from a file?
Code that writes text to a file and reads it back is made of three methods of the Files class. The Files.writeString method writes text to a file, the Files.readAllBytes method reads the bytes stored in the file as they are, and the Files.readString method turns the bytes of the file back into text. A file stores not text but bytes (values you can see as numbers from 0 to 255). So when you write text, it is turned into bytes by a set rule (character encoding), and when you read, the bytes are turned back into text by a rule. The StandardCharsets.UTF_8 part of the code is where that rule is written, and you write it on the writing line and on the reading line. In this lab you change the text to write and the way to read, and the same code is compiled and run, to show the bytes actually stored in the file and the text that was read. (Path.of("memo.txt") is taken to mean the file memo.txt in the folder where the program was run, and other path rules are not covered.)
Checked against real execution · Compiled 9 combinations with javax.tools on JDK 21 and ran each in a new Java process, then checked the stored file bytes against the characters and exceptions that were read
public class Main {
public static void main(String[] args) throws IOException {
// Write: turn the text into bytes by a set rule and store them in the file
Files.writeString(Path.of("memo.txt"), "가A",
StandardCharsets.UTF_8);
// Read 1: read the bytes stored in the file as they are
byte[] bytes = Files.readAllBytes(Path.of("memo.txt"));
// Read 2: turn the bytes of the file back into text by a set rule
String text = Files.readString(Path.of("memo.txt"),
StandardCharsets.UTF_8);
System.out.println(bytes.length);
System.out.println(text);
}
}
The compiler and runtime are JDK 21.0.12.1 (javac 21). All 9 combinations were checked against real runs: the code on the screen (with only the four import lines at the top added) was compiled with javax.tools and run in a new Java process (java -cp . Main) in an empty folder for each combination. After the process ended, the memo.txt in the folder was opened directly to read the bytes actually stored (in hexadecimal) and the size, and I confirmed the number of bytes the program printed, the code points of the characters it read, the exit code, the name of the exception and the line where it occurred (which line of the source), the list of files in the folder after the run (none.txt does not exist and memo.txt does), and that memo.txt did not exist before the run. The four import lines were left out of the screen. That 가 is stored as EA B0 80, 나 as EB 82 98, and the English letters A and B as 41 and 42, and that the ISO_8859_1 rule turns each of the 256 byte values from 0 to 255 into exactly one character, were also checked by a separate run on the same JDK. "Broken characters" is the number of characters read with ISO_8859_1 whose number is 128 or more, and English letters that are the same as the original characters are not counted. Characters that cannot be seen on the screen, such as numbers 128 to 159 (for example U+0080), were actually read, but in the diagram and the step sentences they are written by their number (U+0080 and so on). I opened the documentation and checked it. These are the Java SE 21 API documentation for Files (readAllBytes reads bytes without a rule, readString decodes bytes into characters with the specified character set, and writeString encodes characters into bytes with the specified character set and, with no options, creates the file or empties the existing content and writes), StandardCharsets (the constants UTF_8 and ISO_8859_1), NoSuchFileException (a checked exception thrown when an attempt is made to access a file that does not exist), and Byte (a byte is 8 bits, and how to read it as an unsigned value), and sections 1 and 3 of RFC 3629 (in UTF-8, U+0000 to U+007F take 1 byte, and U+0800 to U+FFFF take 3 bytes). However, the Files documentation does not list NoSuchFileException separately as an exception of these methods and lists only IOException, so that this exception occurs when you read a missing file was observed by running on this JDK, not from the documentation. In the same way, that Path.of("memo.txt") points to a file in the folder where the program was run was only observed by running, and I did not open the documentation to check it. Beyond that, the case where there are invalid bytes when reading as UTF-8 (MalformedInputException), other encodings such as UTF-16, line break characters, file path rules, streams and buffers that write to a file one byte at a time (in-depth lab: I/O streams and buffers), and serialization, which turns an object into bytes to store it (in-depth lab: Serialization), are not covered.
Previous lab: Compilation and the JVM · Next lab: Libraries and dependencies
Struck-through text was removed from the first version of the code; highlighted text was added.