file-io 14 min read

From File to Array (and Back)

Pull data off disk, fill an array, do array work, write the result

In a nutshell

You already know how to do useful things with an array: walk it, search it, sort it, find its average. Last week, the data showed up in main as a literal: int[] scores = {78, 85, 62, 91, 70};. That works for examples, not for real programs. Real data lives in files.

This week’s story is one shape, repeated:

  1. Read a file into an array. A Scanner wrapped around a File is the tool. The methods you’ve used on keyboard input (nextInt, nextLine, hasNextInt) work the same way on a file.
  2. Do array work. Search, sort, find min/max/median, count things. All of this is Week 6 code, unchanged. The array doesn’t know or care where its values came from.
  3. Write the result to a different file. A PrintStream is the tool. System.out is already a PrintStream, so the API is already familiar: out.print, out.println, out.printf.

That’s the entire week. Two new APIs (Scanner-on-File, PrintStream-on-File), one new exception keyword (throws FileNotFoundException), and otherwise the same array techniques you already practiced.

Today in three sentences. A file is just a place where the array’s contents live before the program runs. Once the array is filled, every Week 6 method works exactly the same. Writing the result back is the same print and println you use on System.out, pointed at a different destination.

After this lesson, you will be able to:

  • Read an end-to-end file-to-array-to-file program and explain what each piece does.
  • Identify the two genuinely new APIs (Scanner-on-File, PrintStream-on-File) and the one new bit of syntax (throws FileNotFoundException on main).
  • Pick which Week 6 method (search, sort, mean, max, etc.) goes in the middle of a file-to-file program for a given task.

From CSCD 110. In Python you wrote with open("scores.txt") as f: lines = f.readlines() and got back a list. Java is more verbose because it makes the steps explicit: a File object holds a path, a Scanner reads from it, and you decide one read at a time whether you want a token (nextInt), a line (nextLine), or to peek ahead (hasNextInt). Same job, more visible mechanics.


The story arc: file → array → array work → file

Almost every CSCD 210 file-I/O program — and almost every APE file-I/O exercise — has this exact shape:

  data lives in a file               results live in another file
       (input.txt)                          (output.txt)
            │                                    ▲
            ▼                                    │
   ┌──────────────────┐         ┌──────────────────┐
   │  read into       │         │  write summary   │
   │  an int[]        │  →      │  via PrintStream │
   └──────────────────┘         └──────────────────┘
            │                            ▲
            ▼                            │
        ┌──────────────────────────────────┐
        │  Week 6 array work goes here:    │
        │  search, sort, mean, median, max │
        └──────────────────────────────────┘

Read this carefully. The file is the source of the array’s values, and the second file is the destination of the results. The interesting work — the searching, the sorting, the math — happens on the array in memory, with the same methods you wrote last week.

This is why the file-I/O unit is short. There is not much new programming. There is one new way to fill an array (from a file) and one new way to print a result (to a file). The rest is what you already know.

Common pitfall: assuming files change how arrays work. Some students read “file I/O” and think arrays themselves behave differently when the data came from disk. They don’t. Once the array is constructed and filled, it is exactly the same int[] you indexed and looped over last week. The only difference is who handed you the values. The array doesn’t know.


The end-to-end demo

Here is a complete program. Read it once, top to bottom, before reading the explanation. You will be able to recognize most of it from Week 6.

The program reads test scores from scores.txt, sorts them with selection sort, computes the median, and writes a one-line summary to report.txt.

scores.txt (the input file, one score per line):

78
62
85
91
70

The Java program:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;

public class ScoreReport {

    public static void main(String[] args) throws FileNotFoundException {
        // 1. READ the file into an array.
        Scanner sc = new Scanner(new File("scores.txt"));
        int[] scores = new int[5];
        for (int i = 0; i < 5; i++) {
            scores[i] = sc.nextInt();
        }
        sc.close();

        // 2. WORK on the array. (Week-6 code, unchanged.)
        selectionSort(scores);
        int median = scores[scores.length / 2];   // length is odd here

        // 3. WRITE the result to a different file.
        PrintStream out = new PrintStream(new File("report.txt"));
        out.println("Sorted: " + intArrayToString(scores));
        out.println("Median: " + median);
        out.close();
    }

    // From Week 6.
    public static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) minIndex = j;
            }
            int temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }

    public static String intArrayToString(int[] arr) {
        String s = "[";
        for (int i = 0; i < arr.length; i++) {
            s += arr[i];
            if (i < arr.length - 1) s += ", ";
        }
        return s + "]";
    }
}

The output file report.txt after the program runs:

Sorted: [62, 70, 78, 85, 91]
Median: 78

Now read each numbered comment in turn.

(1) READ. new Scanner(new File("scores.txt")) is the only new line in this section. Everything else — the for loop, the nextInt call, storing into scores[i] — is exactly what you’d write to read five integers from the keyboard. Same Scanner, different source.

(2) WORK. This is all Week 6. selectionSort is the same method body from lesson 6e. The median is scores[scores.length / 2] for an odd-length sorted array. Nothing about the file I/O appears in this block. The array is just an array.

(3) WRITE. new PrintStream(new File("report.txt")) is the only new constructor here. The out.println calls below it are the same println you’ve written a hundred times — they just write to the file instead of the console. The closing call out.close() matters; without it, the file may be empty or truncated.

The throws FileNotFoundException declaration on main is the one new bit of Java syntax. Both new Scanner(new File(...)) and new PrintStream(new File(...)) can throw FileNotFoundException, which is a checked exception (the compiler insists you handle it). Declaring throws on main is the cleanest path for now: it tells the compiler “if this happens, let it crash the program.” You’ll see try/catch and try-with-resources in CSCD 211 — for this course, throws is the convention.

Common pitfall: forgetting throws FileNotFoundException on main. Without it, the program does not compile. The error reads unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown. Add the keyword to the method signature. (Lesson 7b walks through this carefully.)

Check your understanding. Look at the // 2. WORK on the array block. If you replaced selectionSort(scores) with int max = max(scores); (using your max method from Week 6), what would change anywhere else in the program?

Reveal answer

Only the line where you compute and print the result. The reading code does not change — the array still gets filled the same way. The writing code only changes what it prints (out.println("Max: " + max); instead of the median line). The whole point of “work on the array” being its own block is that you can swap one Week 6 method in for another without touching the file plumbing. The file plumbing doesn’t care.

Check your understanding. Why does the program call sc.close() before it constructs the PrintStream and writes the report?

Reveal answer

Two reasons, one practical and one habitual. Practical: once we’re done reading, we want to free the file handle so the operating system isn’t holding it open longer than needed. Habitual: closing each Scanner or PrintStream as soon as you’re done with it makes the close-it-yes-or-no decision local. If you wait until the end of main to close everything, you’ll forget one. Get in the habit of closing where the work for that resource ends.


What’s new vs what’s not new

Two columns. Memorize the left one. The right one is your Week 6 toolkit, untouched.

New this week Same as before
new File("name.txt") — a path object, not the file’s contents. Arrays: declaration, indexing, length, traversal.
new Scanner(new File(path)) — wrap a Scanner around a file. Scanner methods: nextInt, nextDouble, next, nextLine, hasNextInt, hasNextLine.
new PrintStream(new File(path)) — point a PrintStream at a file. print, println, printf — exactly the API of System.out.
throws FileNotFoundException on main — the cleanest way to satisfy the checked-exception rule for now. try/catch and try-with-resources — these exist, but they’re a CSCD 211 topic. You will see them mentioned briefly and then move on.
sc.close() and out.close() — release the file handle when done. Selection sort, insertion sort, linear search, binary search, mean/median/max — all unchanged.

That is the entire surface area of this week. Two constructors, one keyword, two close() calls. Everything else is Week 6.


Wrap up and what’s next

Recap.

  • File I/O is the plumbing between disk and an array. The array work in the middle is the same Week 6 code.
  • Read with new Scanner(new File(path)). Write with new PrintStream(new File(path)). Close both when you’re done.
  • throws FileNotFoundException on main is the default route for this course. try/catch and try-with-resources are CSCD 211 territory.
  • The story arc — read into an array, do array work, write the result — is the shape of nearly every file-I/O problem you will see this week and on the APE.

What you can do now. Read an end-to-end file-to-file program and tell which lines are reading, which are array work, and which are writing. Predict what changes if you swap one Week 6 method (search/sort/stat) into the middle.

Next up: Reading a File with Scanner. The File class as a path (and what that actually means). The Scanner constructor that takes a File. The FileNotFoundException rule: why the compiler refuses to compile without throws, and what the alternatives look like even though we won’t use them yet.


  • Reges & Stepp, Building Java Programs, Chapter 6 sections 6.1 and 6.2 cover Scanner-on-File and the canonical EOF loop.
  • The APE practice exam (login required, EWU SSO) has a File I/O section that uses exactly the file → array → file pattern from this lesson.