File and Scanner I/O Cheat Sheet (new for 2026)

What You Need to Know

File + Scanner I/O in Java is about reading data (text) either from the keyboard (System.in) or from a text file (File) using the Scanner class. For AP CSA-style questions, the core skill is: open the input source correctly, choose the right Scanner methods (token vs line), loop until input ends, parse safely, and close resources.

The core rule

A Scanner reads input in one of two common ways:

  • Token-based: next(), nextInt(), nextDouble(), … (splits on whitespace by default)
  • Line-based: nextLine() (reads the rest of the current line, including spaces)

Critical reminder: Scanner does not automatically “rewind” and nextLine() behaves differently after nextInt()/next() because of leftover newline characters.

Why this matters (AP CSA 2026 angle)

If file I/O is included, you’ll likely be asked to:

  • Read structured text (one item per line, or space-separated tokens)
  • Compute totals/averages, count items meeting a condition, find min/max
  • Build arrays/ArrayLists from file data
  • Parse mixed data types in a predictable format

You need to be fluent with:

  • Constructing Scanner with System.in vs File
  • Using hasNext...() properly
  • Handling FileNotFoundException (checked exception)
  • Avoiding the nextInt() then nextLine() trap

Step-by-Step Breakdown

A. Reading from a file with Scanner (standard pattern)
  1. Import what you need

    • import java.util.Scanner;
    • import java.io.File;
    • import java.io.FileNotFoundException;
  2. Create the File object

    • Use a relative path (common in classes) or an absolute path.
  3. Construct the Scanner

    • new Scanner(file) can throw FileNotFoundException.
  4. Loop to read

    • If reading tokens: while (in.hasNext()) { ... }
    • If reading lines: while (in.hasNextLine()) { ... }
  5. Parse and process

    • Convert to numbers if needed: Integer.parseInt(str), or read with nextInt().
  6. Close the scanner

    • in.close() or use try-with-resources.
Worked template: line-by-line
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class ReadLines {
    public static void main(String[] args) throws FileNotFoundException {
        File f = new File("data.txt");
        Scanner in = new Scanner(f);

        while (in.hasNextLine()) {
            String line = in.nextLine();
            // process line
            System.out.println(line);
        }

        in.close();
    }
}
Worked template: token-by-token (e.g., integers)
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class ReadInts {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner in = new Scanner(new File("nums.txt"));
        int sum = 0;

        while (in.hasNextInt()) {
            sum += in.nextInt();
        }

        in.close();
        System.out.println(sum);
    }
}
B. Reading from keyboard (System.in) with Scanner
  1. Scanner kb = new Scanner(System.in);
  2. Prompt the user (if required).
  3. Read using nextLine() (strings) or nextInt() (numbers).
  4. Deal with the newline issue if mixing methods.

Keyboard template:

import java.util.Scanner;

public class ConsoleInput {
    public static void main(String[] args) {
        Scanner kb = new Scanner(System.in);

        System.out.print("Enter age: ");
        int age = kb.nextInt();
        kb.nextLine(); // consume leftover newline

        System.out.print("Enter name: ");
        String name = kb.nextLine();

        System.out.println(name + " is " + age);
        kb.close();
    }
}
C. Try-with-resources (cleanest for files)

Try-with-resources closes automatically:

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

public class SafeRead {
    public static void main(String[] args) throws FileNotFoundException {
        try (Scanner in = new Scanner(new File("data.txt"))) {
            while (in.hasNextLine()) {
                System.out.println(in.nextLine());
            }
        }
    }
}
Decision points (what loop + method do you use?)
  • File is “one record per line” (names with spaces, sentences, full CSV rows) → use hasNextLine() + nextLine().
  • File is whitespace-separated tokens (ints, words) → use hasNextInt()/hasNext() + nextInt()/next().
  • File has mixed types per line → read the whole line, then parse that line with a second Scanner.

Key Formulas, Rules & Facts

Imports + constructors you must know
ItemWhat it doesNotes
import java.util.Scanner;Allows ScannerRequired for Scanner
import java.io.File;Allows File objectsNeeded for file-based Scanner
import java.io.FileNotFoundException;Allows handling missing fileScanner(File) can throw it
new Scanner(System.in)Reads from keyboardDoesn’t throw checked exceptions
new Scanner(new File("x.txt"))Reads from a fileFile must exist at runtime
Token vs line methods (know these cold)
MethodReads…Common useGotchas
next()next token (up to whitespace)words, simple tokensskips leading whitespace
nextLine()rest of current linefull line, may include spacesafter nextInt(), can read an “empty” line
nextInt()next int tokennumbers filesthrows InputMismatchException if not an int
nextDouble()next double tokendecimal numberssame mismatch risk
hasNext()any token available?token loopsdoesn’t guarantee numeric type
hasNextLine()any line available?line loopssafe for reading lines
hasNextInt()next token is an int?robust int loopavoids mismatch exception
Exceptions you should recognize
ExceptionWhen it happensHow to avoid/handle
FileNotFoundException (checked)file path wrong / file missingthrows in method header or try/catch
InputMismatchExceptioncalling nextInt() on non-int tokenprefer hasNextInt() or read as String then parse
NoSuchElementExceptioncalling next...() when nothing leftcheck with hasNext...() first
IllegalStateExceptionusing scanner after close()don’t reuse closed scanner
File paths (practical rules)
  • Relative path (e.g., "data.txt") means “relative to the program’s working directory.” In many class/IDE setups, that’s the project folder.
  • If a file “exists” but isn’t found, it’s usually in the wrong folder at runtime.

Exam mindset: If they provide a filename, assume it’s accessible at the expected path; focus on correct reading logic and exception handling.

Delimiters (when whitespace isn’t enough)

By default, Scanner splits tokens on whitespace. You can change that:

  • in.useDelimiter(","); for comma-separated tokens (careful: doesn’t automatically trim spaces)
  • in.useDelimiter("\\s*,\\s*"); to split on commas and ignore surrounding spaces

Examples & Applications

Example 1: Sum of integers in a file (unknown count)

File (nums.txt):

10 20 5
7

Key idea: Use hasNextInt() so you don’t crash on non-int.

int sum = 0;
try (Scanner in = new Scanner(new File("nums.txt"))) {
    while (in.hasNextInt()) {
        sum += in.nextInt();
    }
}

Exam variation: They may ask for average too: track count and compute sum / (double) count.

Example 2: Count lines that match a condition (line-based)

File (words.txt): one word per line, possibly blank lines.

Task: Count lines with length at least 5.

int count = 0;
try (Scanner in = new Scanner(new File("words.txt"))) {
    while (in.hasNextLine()) {
        String line = in.nextLine();
        if (line.length() >= 5) {
            count++;
        }
    }
}

Key insight: If blank lines matter, nextLine() preserves them as "" (empty string), which is often what you want.

Example 3: Mixed data per line (parse each line with a second Scanner)

File (grades.txt):

Ava 90 84 100
Ben 72 81

Task: Print each name with their average.

try (Scanner in = new Scanner(new File("grades.txt"))) {
    while (in.hasNextLine()) {
        String line = in.nextLine();
        if (line.isBlank()) continue;

        Scanner row = new Scanner(line);
        String name = row.next();
        int sum = 0;
        int n = 0;
        while (row.hasNextInt()) {
            sum += row.nextInt();
            n++;
        }
        row.close();

        double avg = (n == 0) ? 0.0 : sum / (double) n;
        System.out.println(name + ": " + avg);
    }
}

Why this is powerful: You can do line-based outer loop + token-based inner parsing.

Example 4: CSV-like line with commas

Line: "Lee, 11, 12, 10"

Approach: Split on comma with trimming OR use a delimiter regex.

String line = "Lee, 11, 12, 10";
Scanner row = new Scanner(line);
row.useDelimiter("\\s*,\\s*");
String name = row.next();
int a = row.nextInt();
int b = row.nextInt();
int c = row.nextInt();
row.close();

Key insight: The delimiter "\\s*,\\s*" eats optional whitespace around commas.


Common Mistakes & Traps

  1. Mixing nextInt() (or next()) with nextLine() without consuming the newline

    • What goes wrong: nextLine() returns the rest of the current line (often empty).
    • Why: nextInt() leaves the "\n" in the input buffer.
    • Fix: After nextInt(), do one extra nextLine() to consume the leftover newline before reading the next real line.
  2. Using while (in.hasNextLine()) but reading with nextInt() inside

    • What goes wrong: Your loop condition checks for lines, but you consume tokens; this can behave unpredictably and is logically mismatched.
    • Fix: Match them: hasNextInt() with nextInt(), or hasNextLine() with nextLine().
  3. Calling nextInt() without checking hasNextInt()

    • What goes wrong: InputMismatchException if the next token isn’t an int.
    • Fix: Use hasNextInt() or read as String then parse with Integer.parseInt(...) (and only if you know it’s valid).
  4. Forgetting FileNotFoundException is checked

    • What goes wrong: Code won’t compile if you don’t handle it.
    • Fix: Either add throws FileNotFoundException to the method header or use a try/catch.
  5. Assuming the file path is the same as where the source code is

    • What goes wrong: Runtime FileNotFoundException even though you “see the file” in your IDE.
    • Fix: Know the working directory (often project root). Put the file there or use the correct relative path.
  6. Not closing the Scanner (resource leak)

    • What goes wrong: Usually not an immediate crash in small programs, but it’s bad practice and can matter.
    • Fix: Use try-with-resources: try (Scanner in = ...) { ... }.
  7. Using hasNext() to control numeric input loops

    • What goes wrong: hasNext() may be true for a non-numeric token, then nextInt() crashes.
    • Fix: For ints use hasNextInt(); for doubles use hasNextDouble().
  8. Expecting Scanner to read characters one-by-one

    • What goes wrong: Scanner is not character-oriented; it tokenizes.
    • Fix: For character-level processing, read a line with nextLine() then use charAt(i) in a loop.

Memory Aids & Quick Tricks

Trick / mnemonicWhat it helps you rememberWhen to use it
“Condition matches consumption”Your hasNextX() should match your nextX()Prevents mismatched loops
“Int then Line = eat the NL”After nextInt(), do nextLine() before reading a real lineFixes empty-string nextLine() bug
“Outer lines, inner tokens”Use nextLine() outer loop, then new Scanner(line) to parseMixed-format per line files
“Use the hasNextType() guard”Avoid InputMismatchExceptionAny uncertain numeric input
Delimiter regex: \\s*,\\s*Comma-separated values with optional spacesBasic CSV-ish input

Quick Review Checklist

  • You can construct a Scanner from System.in and from a File.
  • You remember required imports: Scanner, File, FileNotFoundException.
  • You handle file input either by throws FileNotFoundException or try/catch.
  • You choose token (nextInt(), next()) vs line (nextLine()) based on file format.
  • Your loop condition matches your read method: hasNextInt() with nextInt(), hasNextLine() with nextLine().
  • You avoid the nextInt()nextLine() trap by consuming the newline.
  • You close the scanner (best: try-with-resources).
  • You can parse a complex line by creating a second Scanner on the line.

You’ve got this—practice 2–3 file formats and you’ll be ready for whatever they throw at you.