Level-up challenge · CSCD210

One program that writes a file and reads it back into an array

You have finished the catch-up path and you want to write one program that makes a file and then reads it back the way a lab will ask you to.

Unlocked at the end of: Arrays and file I/O, from zero, after the room count-allocate-fill. Room 15 closes the path. After it you have written a file, opened it, read it to the end, and built the count pass and the fill pass yourself, which is exactly the program this challenge asks for.

Outcomes this shows6Inputs it is run on4Timeabout 60 minutesDifficulty3 of 3

What this shows you can do

Each line below is one outcome, written the way the course records it. A program that does the whole task shows all of them at once.

  1. Student can construct a PrintStream over a File, declare or catch the FileNotFoundException the constructor throws, write output with println/printf, and close() the stream to flush buffered bytes.

    In this program: Everything the program reports comes back out of the file it wrote, so a program that does not construct the stream, does not declare the exception, or writes nothing produces no report at all.

    Not shown by a run:"close() the stream to flush buffered bytes". Removing the close from the writing method changed no line of any check, because PrintStream(File) wraps a FileOutputStream with no byte buffer of its own and the bytes reach the operating system as each println runs. The guarantee still needs the close and the spec still asks for it, and a run is not what shows it.

  2. Student can construct a Scanner over a file using the two-step idiom new Scanner(new File(filename)), declare or catch the FileNotFoundException the constructor throws, and close the Scanner to release the file handle when finished.

    In this program: Measured: replacing the two-step idiom with new Scanner(filename) in the counting pass reports zero readings and then ends with ArrayIndexOutOfBoundsException, because the scanner reads the characters of the file name instead of the file.

    Not shown by a run:"close the Scanner to release the file handle when finished". A comparison of what a program prints cannot see a close.

  3. Student can import java.io.FileNotFoundException, declare it with throws on every method that constructs a Scanner on a File, distinguish it from FileSystemNotFoundException in java.nio.file, and explain why a pre-check (e.g., exists() or canRead()) does not remove the declaration requirement.

    In this program: Three of the four required headers already carry the line, and main calls all three. The header of main is not given, so the program does not compile until the student carries the line up to it or handles it there.

    Not shown by a run:"distinguish it from FileSystemNotFoundException" and "explain why a pre-check does not remove the declaration requirement". Both of those are said. What a run shows is that the import and the declarations are right, because nothing compiles otherwise.

  4. Student can write a while (sc.hasNextLine()) loop to read every line of a file, recognize the guard-and-read pairing, and adapt the pattern for counting lines (Pass 1 of count-allocate-fill) and for skipping a header before the loop.

    In this program: The file has a header line and then one reading per line, so the counting pass has to skip before the loop and pair one guard with one read inside it. Measured: a loop that reads in the guard and again in the body counts half the lines, or ends with NoSuchElementException when the count left is odd.

  5. Student can produce a Pass-1 counting method that takes a filename, opens a fresh Scanner, walks to EOF using a hasNextLine (or hasNextX) guard, increments a counter while discarding the read value, closes the Scanner, and returns the count.

    In this program: The first line of the report is the count this method returns, and the four checks have four different counts, so a count that comes from anywhere else matches at most one of them.

    Not shown by a run:"closes the Scanner". Not visible in output, the same limit as the Scanner leaf above.

  6. Student can produce a Pass-2 method that takes a filename and a count, opens a fresh Scanner, allocates an array of exactly count slots, fills it with a counted for loop using the appropriate typed read, closes the Scanner, and returns the array.

    In this program: The report prints the array's own slot count and its first and last values, so an array allocated larger than the count shows a wrong slot count and a last value of zero.

    Not shown by a run:"closes the Scanner", as above.

What to build

Write one program named ReadingsFile.

It reads from standard input. The first number is how many readings follow. Each reading after that is a whole number, and there is at least one.

The program does three things, in order.

First it writes a file named readings.txt in the folder it is running in. The first line of that file is the single word readings. Every line after that is one reading, in the order they arrived.

Then it reads that file back twice. The first pass counts how many readings the file holds, which is every line after the header. The second pass builds an int[] with exactly that many slots and fills it with the readings from the file. Each pass opens the file for itself.

Then it prints five lines, in this order, with the labels spelled exactly as shown here:

readings in file
slots
first
last
sum

Each line is the label, a colon, one space, and the value. Print nothing else, and print no prompt. Nothing in the output names the folder the program ran in.

Every method that opens a file carries throws FileNotFoundException. Three of the four headers below already have it. Java will tell you if another method needs it too.

The rest of the program is yours to shape.

Write these methods with these headers

One worked example

The first of the inputs, with what the program prints for it.

Five readings, all positive

The count in the report has to come from the file rather than from standard input, which is what the second and third lines of the report separate.

Input
5
71
68
78
62
69
Output
readings in file: 5
slots: 5
first: 71
last: 69
sum: 348

How your program is checked

Your program is run once for each input and its output is compared with what is shown. The worked example above is the first of them. You can run every one of them yourself before you hand anything in.

One reading

The smallest file the spec allows, one header line and one reading, where a counting pass that includes the header is off by a factor of two rather than by a little.

Input
1
40
Output
readings in file: 1
slots: 1
first: 40
last: 40
sum: 40

Eight readings, mixed signs, with a repeated value

Negative numbers are written and read back as tokens, so this is the check that a minus sign survives the round trip through the file.

Input
8
-3
12
5
-8
20
1
20
7
Output
readings in file: 8
slots: 8
first: -3
last: 7
sum: 54

Three readings, all negative

A third count, so a program that returns a fixed number from the counting pass cannot pass more than one check.

Input
3
-12
-7
-25
Output
readings in file: 3
slots: 3
first: -12
last: -25
sum: -44

What to watch for

Each one is copied from the notes for the rooms this challenge draws on, with what a run shows when it happens.

What this puts on your resume

You have written Java that creates a text file, reads it back in two separate passes to learn how many records it holds, and loads those records into an array sized to fit them.

What the program needs where it runs

Notes for the author, not part of the student page

This block is here so the manifest can be reviewed on the page instead of in the file. It is not rendered on a student page.

Why this is not ready to offer

Three of the six leaves this challenge certifies are not a subject leaf in any room of the path. A student who finishes the path has not been given them, so this challenge cannot be offered at the end of the path as it stands today.

Two more rooms on the path, both after file-into-an-array. One that writes a PrintStream, and one that is the count-allocate-fill pattern end to end. Both already exist as spine leaves with stems, so both rooms are a manifest edit and no new curriculum.

Outcomes considered and left out

Why a run cannot see some clauses

Scope decisions

Carried in from earlier rooms

Assumed from earlier in the course

Where the expected output came from

Provenance