Chapter 5 · Real programs
Files
Step 1 of 19 · Concept
Files outlive your program
Your variables live in memory. When the program ends, its memory is cleared (lesson 2). A file lives in storage, and stays.
In this lesson you will:
- write text into a file and read it back,
- read a file line by line,
- turn a file of data into a report.
Step 2 of 19 · Quiz
What is left?
A program writes the text "Buy milk" into notes.txt, then ends. What is still there?
Step 3 of 19 · Concept
A Path names a file, Files does the work
Java's file tools are in the package java.nio.file. A Path names a file. The class Files has static
methods that write and read one.
| you write | it does |
|---|---|
Path.of("notes.txt") | names a file; it does not make one |
Files.writeString(file, text) | makes the file, or replaces what it held |
Files.readString(file) | returns all of the file as one String |
Files.exists(file) | true when there is such a file |
Step 4 of 19 · Demo
Write a file and read it back
Press Run. The program writes notes.txt, reads it back, then asks whether two files exist.
Step 5 of 19 · Concept
The file is in the working folder
A name without a folder, like notes.txt, means a file in the working folder: the folder the program runs in.
Here that is the block's own folder.
See for yourself. Choose Open in the terminal in the ⋯ menu, then type ls and cat notes.txt. The program
has ended, and the file is still there.
Step 6 of 19 · Concept
Files can fail
Reading and writing can go wrong. Storage may be full, or the file may not exist. Reading missing.txt with
Files.readString throws a NoSuchFileException.
Each of these failures is an IOException, or a kind of it. IOException is checked (lesson 14). So a method that
uses Files must do one of two things:
- catch
IOException, or - say
throws IOExceptionin its header, asmaindoes inNotes.
Step 7 of 19 · Quiz
Without throws
You delete throws IOException from the header of main in Notes. What happens when you press Run?
Step 8 of 19 · Exercise
Your turn: save a list
Write the body of save. It writes the items into file, numbered, one per line:
- Build the whole text in one
Stringwith a loop. - Write it with one
Files.writeString.
main deletes an old todo.txt first, so it prints what this run wrote. The output must be exactly:
1. Buy milk
2. Call Ada
3. Learn Java
Start with String text = ""; and add one line per item. Each line ends with "\n".
Loop with for (int i = 0; i < items.size(); i++). The number of item i is i + 1.
text += (i + 1) + ". " + items.get(i) + "\n";
After the loop: Files.writeString(file, text);
Step 9 of 19 · Concept
A file of lines
Most data files are lines: one record, one score or one sentence per line.
Files.readAllLines(file) reads a file and returns a List<String> (lesson 13). Each line is one element, without
its line ending.
Step 10 of 19 · Concept
Cut a line into pieces
line.split(" ") cuts a line at every space. It returns the pieces as an array (lesson 10), without the spaces.
Another separator works the same way: "Ada,92".split(",") gives the two pieces "Ada" and "92".
Step 11 of 19 · Quiz
What will it print?
Type exactly what this prints.
String[] words = "and Java runs".split(" ");
System.out.println(words.length);
System.out.println(words[1]);
String[] parts = "Ada,92".split(",");
System.out.println(parts[0] + " has " + parts[1]);
Step 12 of 19 · Demo
See it run
Run it and compare with your answer.
Step 13 of 19 · Demo
Read the lines of a file
poem.txt is the second tab in the editor. Run the program: it reads that file line by line and counts the words
of each line.
Step 14 of 19 · Try it
Try it: a fifth line
Open the tab poem.txt and add a fifth line: and so do you. Then press Run.
The editor saves your file before the program starts, so the program reads your version. The last two lines must be:
5: and so do you (4 words)
Lines: 5
The new line goes at the end of poem.txt, on a line of its own. Then press Run.
Step 15 of 19 · Exercise
Your turn: count the words
Write two methods:
countWords: the number of words in all the lines;longest: the longest line (the first one, if two are as long).
The program must print exactly:
Lines: 4
Words: 23
Longest: for a machine that did not exist yet
A line's number of words is the number of pieces split(" ") gives: line.split(" ").length.
For longest, keep the best line so far in a variable. Replace it when a line is longer: line.length() > best.length().
int count = 0;
for (String line : lines) {
count += line.split(" ").length;
}
return count;
Step 16 of 19 · Concept
From a line to data
A line such as Ada,92 holds two values. Three steps turn it into data:
line.split(",")cuts it into"Ada"and"92".Integer.parseInt("92")turns the text into theint92. For"abc"it throws aNumberFormatException(lesson 14).putstores it in a map, from the name to the score.
The map's type can be Map<String, Integer>. Map is an interface, as List is (lesson 15): HashMap and
TreeMap both implement it.
Step 17 of 19 · Check yourself
Check yourself: a grade report
grades.txt has one student per line, name,score. One line is broken.
Write load and report from their comments. main writes the report into report.txt and prints that file.
The output must be exactly:
Skipped: Linus,abc
Ada: 92 pass
Alan: 47 fail
Bo: 70 pass
Grace: 85 pass
Average: 73.50
load follows the step From a line to data, with the put inside a try. report builds one String, as save did.
Step 18 of 19 · Challenge · optional
Challenge: sort a file
Optional. It earns the lesson's third star.
names.txt holds four names in no order. Write them into sorted.txt in alphabetical order, one per line. The
program then prints that file:
Ada
Alan
Grace
Linus
Sort the list as lesson 18 did, with a lambda: names.sort((a, b) -> a.compareTo(b));
Files.write(out, names) writes a whole list into a file, one element per line.
Step 19 of 19 · Recap
Recap
- Memory is cleared when a program ends. A file in storage stays.
Path.of("notes.txt")names a file in the working folder.Files.writeStringandFiles.readStringcopy text into it and back.Files.readAllLinesgives oneStringper line.splitandInteger.parseIntturn a line into data, such as a map from names to scores.Filesmethods may throw the checkedIOException: catch it or declare it.
Next: lesson 20 is practice: the classic ways to search and sort, written by hand.
Review
3 questions from this lesson, in a new order each time. Answer from memory: 2 of 3 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Notes {
public static void main(String[] args) throws IOException {
Path file = Path.of("notes.txt");
Files.writeString(file, "Buy milk\nCall Ada\n");
String text = Files.readString(file);
System.out.print(text);
boolean found = Files.exists(file);
boolean other = Files.exists(Path.of("missing.txt"));
System.out.println("notes.txt exists: " + found);
System.out.println("missing.txt exists: " + other);
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Todo {
static void save(List<String> items, Path file)
throws IOException {
}
public static void main(String[] args) throws IOException {
Path file = Path.of("todo.txt");
Files.deleteIfExists(file);
List<String> items =
List.of("Buy milk", "Call Ada", "Learn Java");
save(items, file);
if (Files.exists(file)) {
System.out.print(Files.readString(file));
} else {
System.out.println("There is no todo.txt");
}
}
}
public class Split {
public static void main(String[] args) {
String[] words = "and Java runs".split(" ");
System.out.println(words.length);
System.out.println(words[1]);
String[] parts = "Ada,92".split(",");
System.out.println(parts[0] + " has " + parts[1]);
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Poem {
public static void main(String[] args) throws IOException {
Path file = Path.of("poem.txt");
List<String> lines = Files.readAllLines(file);
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
String[] words = line.split(" ");
System.out.printf("%d: %s (%d words)%n",
i + 1, line, words.length);
}
System.out.println("Lines: " + lines.size());
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class Poem {
public static void main(String[] args) throws IOException {
Path file = Path.of("poem.txt");
List<String> lines = Files.readAllLines(file);
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
String[] words = line.split(" ");
System.out.printf("%d: %s (%d words)%n",
i + 1, line, words.length);
}
System.out.println("Lines: " + lines.size());
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class WordCount {
static int countWords(List<String> lines) {
return 0;
}
static String longest(List<String> lines) {
return "";
}
public static void main(String[] args) throws IOException {
Path file = Path.of("story.txt");
List<String> lines = Files.readAllLines(file);
System.out.println("Lines: " + lines.size());
System.out.println("Words: " + countWords(lines));
System.out.println("Longest: " + longest(lines));
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.TreeMap;
public class Grades {
// each line as name and score, in a TreeMap;
// a score that is not a number: print
// "Skipped: " and the line, and leave it out
static Map<String, Integer> load(Path file)
throws IOException {
return new TreeMap<>();
}
// one line per student: name, score, and
// "pass" for 50 or more, else "fail";
// last, the average with two decimals
static String report(Map<String, Integer> grades) {
return "";
}
public static void main(String[] args) throws IOException {
Path data = Path.of("grades.txt");
Map<String, Integer> grades = load(data);
Path out = Path.of("report.txt");
Files.writeString(out, report(grades));
System.out.print(Files.readString(out));
}
}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class SortFile {
public static void main(String[] args) throws IOException {
Path out = Path.of("sorted.txt");
Files.deleteIfExists(out);
Path source = Path.of("names.txt");
List<String> names = Files.readAllLines(source);
// sort names, then write them into out
if (Files.exists(out)) {
System.out.print(Files.readString(out));
} else {
System.out.println("There is no sorted.txt");
}
}
}