Browse Certification Practice Tests by Exam Family

Java 21 1Z0-830: Using Java I/O API

Try 10 focused Java 21 1Z0-830 questions on Using Java I/O API, with explanations, then continue with IT Mastery.

On this page

Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.

Try Java 21 1Z0-830 on Web View full Java 21 1Z0-830 practice page

Topic snapshot

FieldDetail
Exam routeJava 21 1Z0-830
Topic areaUsing Java I/O API
Blueprint weight7%
Page purposeFocused sample questions before returning to mixed practice

How to use this topic drill

Use this page to isolate Using Java I/O API for Java 21 1Z0-830. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.

PassWhat to doWhat to record
First attemptAnswer without checking the explanation first.The fact, rule, calculation, or judgment point that controlled your answer.
ReviewRead the explanation even when you were correct.Why the best answer is stronger than the closest distractor.
RepairRepeat only missed or uncertain items after a short break.The pattern behind misses, not the answer letter.
TransferReturn to mixed practice once the topic feels stable.Whether the same skill holds up when the topic is no longer obvious.

Blueprint context: 7% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.

Sample questions

These questions are original IT Mastery practice items aligned to this topic area. They are designed for self-assessment and are not official exam questions.

Question 1

Topic: Using Java I/O API

An upload service receives files that may be images, ZIP archives, or text. It must copy a source Path src to a destination Path dst byte-for-byte without interpreting the content. Files can be large, so the implementation should stream data rather than load the whole file. Which I/O choice correctly fits this task?

Options:

  • A. Use Files.readString() and Files.writeString().

  • B. Use ObjectInputStream and ObjectOutputStream.

  • C. Use BufferedInputStream and BufferedOutputStream over file streams.

  • D. Use BufferedReader and BufferedWriter with UTF-8.

Best answer: C

Explanation: The task requires preserving raw bytes for arbitrary file types. Byte streams are the correct abstraction, and buffered byte streams allow efficient streaming without loading the whole file into memory.

Java separates byte-oriented I/O (InputStream/OutputStream) from character-oriented I/O (Reader/Writer). A byte-for-byte copy of arbitrary formats must not decode bytes into characters, because decoding can fail or re-encoding can change the bytes. Wrapping file streams in BufferedInputStream and BufferedOutputStream keeps the operation streaming and efficient for large files; transferTo can then copy bytes from input to output without loading the whole file. Readers, writers, and string APIs fit text processing, not arbitrary binary copying.

  • Character streams decode and encode data, so they are unsafe for ZIP files or images.
  • String file APIs are text-oriented and read the file content into memory.
  • Object streams write Java serialization data, not a transparent copy of arbitrary file bytes.

Question 2

Topic: Using Java I/O API

A Java 21 batch job must write text to reports/2025/summary.txt. The directory tree reports/2025 may or may not already exist. If summary.txt already exists, its old contents must be replaced.

Path dir = Path.of("reports", "2025");
Path file = dir.resolve("summary.txt");

Which snippet correctly implements this with NIO.2?

Options:

  • A. Files.createFile(file); Files.writeString(file, text);

  • B. Files.createDirectories(dir); Files.writeString(file, text);

  • C. Files.createDirectory(dir); Files.writeString(file, text);

  • D. if (Files.exists(file)) Files.delete(file); Files.writeString(file, text);

Best answer: B

Explanation: The directory path must be created safely before writing the file. Files.createDirectories() handles an already-existing directory tree, and Files.writeString() with no open options creates the file if needed or truncates it if it already exists.

NIO.2 separates directory creation from file writing. Files.createDirectories(dir) creates all missing directories in the path and does not fail merely because the directories already exist. After that, Files.writeString(file, text) uses the default open options for writing: create the file if it is absent, truncate it if it exists, and write the supplied text.

The key takeaway is that parent directories are not automatically created by file-writing methods.

  • Creating the file first fails if summary.txt already exists and can also fail when parent directories are missing.
  • Single directory creation with createDirectory() does not create missing intermediate parent directories.
  • Delete then write still fails when the directory tree is missing and adds an unnecessary existence-check race.

Question 3

Topic: Using Java I/O API

An application must return the number of lines in a text file, or -1 if the file cannot be opened or read. A developer writes:

static long lineCount(Path path) {
    Stream<String> lines;
    try (BufferedReader br = Files.newBufferedReader(path)) {
        lines = br.lines();
    } catch (IOException e) {
        return -1;
    }
    return lines.count();
}

Which refactoring is the best fix?

Options:

  • A. Declare throws IOException and keep lines.count() after the try block.

  • B. Count inside the try-with-resources and catch IOException | UncheckedIOException.

  • C. Wrap only lines.count() in catch (IOException e) after the try block.

  • D. Check Files.exists(path) before opening and keep the current structure.

Best answer: B

Explanation: BufferedReader.lines() returns a lazy stream backed by the reader. The current code closes the reader before the terminal operation runs, so the stream cannot safely read from it. Counting inside the try-with-resources keeps the resource open and allows both open/close IOException and lazy-read UncheckedIOException to be handled.

The core issue is resource state: a stream from BufferedReader.lines() is not an independent copy of the file contents. It reads lazily from the BufferedReader, so the terminal operation must occur while the reader is still open. Also, stream operations cannot throw checked IOException; I/O failures encountered while reading through the stream are wrapped in UncheckedIOException. For the stated requirement, the refactor should both keep the terminal operation inside the try-with-resources block and handle IOException | UncheckedIOException. Simply declaring throws IOException does not fix the closed-reader problem.

  • Throwing IOException does not help because the reader has already been closed before count() runs.
  • Catching IOException around count fails because Stream.count() does not declare checked IOException.
  • Checking existence first does not prove the file can be read and does not keep the reader open.

Question 4

Topic: Using Java I/O API

A utility method must count every regular file in a directory tree rooted at root. The tree contains only directories and regular files. The method may declare throws IOException, and traversal resources must be closed promptly. Which method body best meets the requirement?

Options:

  • A. try (var paths = Files.find(root, 1, (p, a) -> a.isRegularFile())) { return paths.count(); }

  • B. try (var paths = Files.list(root)) { return paths.filter(Files::isRegularFile).count(); }

  • C. return Files.walk(root).filter(Files::isRegularFile).count();

  • D. try (var paths = Files.walk(root)) { return paths.filter(Files::isRegularFile).count(); }

Best answer: D

Explanation: Files.walk(root) is the appropriate stream-returning API for recursive traversal. Because the stream holds file-system resources, it should be used in a try-with-resources statement so it is closed after the terminal operation completes.

NIO.2 traversal methods such as Files.list(), Files.walk(), and Files.find() return streams that may hold open directory resources. The stream should be closed, typically with try-with-resources. For this requirement, Files.walk(root) is recursive, so filtering it with Files::isRegularFile and then calling count() counts files throughout the tree. Files.list(root) is only a shallow listing, and Files.find(root, 1, ...) is limited by its maximum depth. A stream pipeline without try-with-resources may produce the count, but it does not meet the prompt’s resource-closing requirement.

  • Missing close fails because the stream from Files.walk() is not closed promptly.
  • Shallow listing fails because Files.list() only lists direct entries of root.
  • Limited depth fails because Files.find(root, 1, ...) does not traverse the whole tree.

Question 5

Topic: Using Java I/O API

Your command-line utility runs from a real terminal, so System.console() is not null. It must read exactly one line of human-entered text and append it as ordinary UTF-8 text to notes.txt, adding a platform line separator. Which API pairing is most appropriate?

Options:

  • A. Console.readLine() with Files.newBufferedWriter(...)

  • B. ObjectInputStream.readObject() with ObjectOutputStream.writeObject()

  • C. System.in.readAllBytes() with Files.newOutputStream(...)

  • D. DataInputStream.readUTF() with DataOutputStream.writeUTF()

Best answer: A

Explanation: Text data should be handled with character-oriented APIs that understand characters and encodings. Console.readLine() reads a line of terminal text, and Files.newBufferedWriter(...) can append UTF-8 text and add a line separator with newLine().

Java I/O separates byte-oriented streams from character-oriented readers and writers. For human-entered console text, Console.readLine() returns a String without requiring you to decode bytes manually. For file text output, Files.newBufferedWriter(path, UTF_8, CREATE, APPEND) creates a BufferedWriter that encodes characters as UTF-8 and can write a platform line separator with newLine(). Byte streams are appropriate for raw bytes, while data and object streams write structured binary formats, not plain text files. The key distinction is ordinary encoded text versus binary data formats.

  • Raw bytes fails because readAllBytes() and newOutputStream() do not provide line-oriented text handling or charset-aware writing.
  • Data streams fail because writeUTF() writes a length-prefixed modified UTF-8 binary format, not a plain text line.
  • Object streams fail because serialization writes object metadata and binary content, not ordinary human-readable UTF-8 text.

Question 6

Topic: Using Java I/O API

An application writes an audit file. If a write operation fails, the file handle may remain open. The team also wants close failures to be handled by Java’s normal exception mechanism rather than replacing the main write failure. Which refactor is the best fix?

static void writeLines(Path file, List<String> lines) throws IOException {
    BufferedWriter out = Files.newBufferedWriter(file);
    for (String line : lines) {
        out.write(line);
        out.newLine();
    }
    out.close();
}

Options:

  • A. Call out.flush() before the loop and keep out.close() after it.

  • B. Use try (BufferedWriter out = Files.newBufferedWriter(file)) around the loop.

  • C. Replace BufferedWriter with PrintWriter because it closes itself.

  • D. Move out.close() to a plain finally block outside the loop.

Best answer: B

Explanation: The best refactor is a try-with-resources statement that creates the BufferedWriter in the resource header. It guarantees close() is called when the block exits, including when write() or newLine() throws an IOException.

For I/O resources such as BufferedWriter, try-with-resources is the idiomatic Java 21 way to ensure reliable cleanup. The resource must implement AutoCloseable, and BufferedWriter does. When the loop completes or throws, Java automatically calls close(). If both the write operation and close() throw exceptions, the write failure remains the primary exception and the close failure is recorded as suppressed. This is safer and clearer than manually placing close() after the work.

  • Flush before writing does not help because close() is still skipped if a write operation throws.
  • Plain finally can close the writer, but a thrown close() can replace the original write exception.
  • Changing to PrintWriter solves the wrong problem; it still needs closing and can hide I/O errors.

Question 7

Topic: Using Java I/O API

A binary archiving utility needs to inspect and write a small header, return to the marked position if supported, skip one byte, transfer the rest, and flush the destination. Which declaration for source and target lets the method compile without casts or wrappers?

static void archive(____ source, ____ target) throws IOException {
    byte[] buf = new byte[8];
    if (source.markSupported()) {
        source.mark(8);
        int n = source.read(buf);
        if (n > 0) target.write(buf, 0, n);
        source.reset();
    }
    source.skip(1);
    source.transferTo(target);
    target.flush();
}

Options:

  • A. Reader source, OutputStream target

  • B. Reader source, Writer target

  • C. OutputStream source, InputStream target

  • D. InputStream source, OutputStream target

Best answer: D

Explanation: The code uses byte-oriented APIs, so the source must be an InputStream and the destination must be an OutputStream. Input-side operations such as read, skip, mark, reset, and transferTo belong on the source, while write and flush belong on the destination.

InputStream is the byte-input API. It has read(byte[]), skip(long), mark(int), reset(), markSupported(), and transferTo(OutputStream). OutputStream is the byte-output API. It has write(byte[], int, int) and flush(). The byte[] buf is also decisive: Reader and Writer are character APIs and use char[] or String, not byte[], for their array-based operations.

The key takeaway is to keep input operations on input types and output operations on output types, while matching byte streams with byte buffers.

  • Reversed streams fail because OutputStream is not a readable, skippable, markable source.
  • Character pair fails because Reader and Writer do not use byte[] for array-based read and write.
  • Mixed character/byte pair fails because Reader.transferTo requires a Writer, not an OutputStream.

Question 8

Topic: Using Java I/O API

Which statement is correct about the Java 21 java.nio.file.Files convenience methods for reading and comparing file contents?

Options:

  • A. Files.writeString(path, text) appends by default.

  • B. Files.lines(path) returns a stream that should be closed.

  • C. Files.mismatch(p1, p2) returns 0 for equal files.

  • D. Files.readString(path) uses the platform default charset.

Best answer: B

Explanation: Files.lines(Path) returns a Stream<String> backed by an open file resource. Because the stream encapsulates I/O resources, code should close it explicitly, usually with try-with-resources.

The core rule is that Files.lines(Path) is stream-based I/O, not an eager list read. It opens the file and returns a lazily populated stream whose underlying resource is closed when the stream is closed. By contrast, Files.readString(Path) reads the file content into a String using UTF-8 by default, and Files.writeString(Path, CharSequence) writes using UTF-8 by default with create/truncate/write behavior when no open options are supplied. Files.mismatch(Path, Path) reports the first differing byte position and returns -1L when file contents are equal.

  • Default charset is not the rule for readString(Path); the no-charset overload uses UTF-8.
  • Append by default is wrong for writeString; appending requires an append open option.
  • Equal mismatch value is wrong because Files.mismatch returns -1L, not 0, for equal contents.

Question 9

Topic: Using Java I/O API

What is the result of running the following Java 21 code?

import java.io.*;

public class Demo {
    public static void main(String[] args) {
        var reader = new BufferedReader(new StringReader("red\nblue"));
        try {
            try (reader) {
                System.out.print(reader.readLine());
            }
            System.out.print("," + reader.readLine());
        } catch (IOException e) {
            System.out.print(":IO");
        }
    }
}

Options:

  • A. It prints red,blue.

  • B. It prints red,:IO.

  • C. It prints red:IO.

  • D. It does not compile because IOException is not declared by main.

Best answer: C

Explanation: The variable reader remains in scope, but try-with-resources closes it at the end of the inner try. The later readLine() call on the closed BufferedReader throws an IOException, which the outer catch handles by printing :IO.

Try-with-resources closes every resource named in its resource specification when the block finishes, even if the variable was declared before the try. In Java 21, an effectively final variable such as reader may be used as the resource. The calls that can throw IOException are inside a try with a matching catch, so no throws clause is required on main. After the inner try prints the first line, reader is closed. The later expression "," + reader.readLine() tries to read from the closed BufferedReader; readLine() throws IOException before System.out.print is invoked, so the comma is not written. The catch then prints :IO.

  • Resource remains open fails because try-with-resources closes reader after the inner block.
  • Comma is printed first fails because the string concatenation argument is evaluated before print() is called.
  • Missing declaration fails because the outer catch (IOException e) handles the checked I/O operations.

Question 10

Topic: Using Java I/O API

A log-cleanup utility must count all regular files below root, including files in nested directories at any depth. Assume root is a directory and necessary imports exist. The method may propagate failures, but traversal resources must be released promptly even if the terminal operation fails. Which body should be used?

long countRegular(Path root) throws IOException {
    // body goes here
}

Options:

  • A. try (Stream<Path> paths = Files.walk(root)) { return paths.filter(Files::isRegularFile).count(); }

  • B. return Files.walk(root).filter(Files::isRegularFile).count();

  • C. try (Stream<Path> paths = Files.list(root)) { return paths.filter(Files::isRegularFile).count(); }

  • D. try (Stream<Path> paths = Files.find(root, 1, (p, a) -> a.isRegularFile())) { return paths.count(); }

Best answer: A

Explanation: NIO.2 traversal methods such as Files.walk() return streams that hold file-system resources. The stream must be closed, typically with try-with-resources, and the terminal operation must run inside that block.

Files.walk(root) recursively traverses the directory tree and returns a Stream<Path>. That stream implements AutoCloseable through BaseStream, so it should be used in a try-with-resources statement. The pipeline and terminal operation must execute before the resource block exits; then Java closes the stream whether counting succeeds or an exception occurs. A terminal operation such as count() consumes the stream but does not automatically close it. Files.list(root) is only one directory level, while Files.find(root, 1, ...) limits traversal depth to the root and its immediate children.

  • Terminal operation closure fails because count() does not automatically close a stream returned by Files.walk().
  • Nonrecursive listing fails because Files.list() only lists entries directly in root.
  • Limited depth search fails because maxDepth of 1 does not include files in deeper nested directories.

Continue with full practice

Use the Java 21 1Z0-830 Practice Test page for the full IT Mastery route, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.

Try Java 21 1Z0-830 on Web View Java 21 1Z0-830 Practice Test

Free review resource

Read the Java 21 1Z0-830 Cheat Sheet on Tech Exam Lexicon, then return to IT Mastery for timed practice.

Revised on Thursday, May 14, 2026