Kodrill

ファイル I/O

Java SE 17 Gold (1Z0-826-JPN) 試験

Console と標準入出力/バイト・文字の I/O ストリーム/シリアライズ/Path と Files/Files.lines・walk などのストリーム操作

問題数
20 問
合格ライン
65%
実行して確認済み
16 問
この分野の要点を読む7 章・約 20 分。実行して確かめたコード例と、試験でよくある引っかけをまとめています

ログインなしで試す

無料の 5 問を、1問ごとに正誤と解説を見ながら解けます。解答は保存されません。

5 問を試す

無料登録して学習を記録する

学習履歴・ダッシュボード・ブックマーク・模試モードが使えます。

★ 残り 15 問はプレミアム会員限定です

無料プランでは先頭 5 問まで解けます。プレミアムなら全問題・苦手問題の復習・広告非表示が使えます。
料金プランを見る

問題と解説を見る (無料)

登録しなくても、次の5問は問題文と解説をそのまま読めます。

ファイル I/Oの要点

内容の確認日: 2026-10-04

この分野では、java.io パッケージの従来のストリーム (Reader・Writer・InputStream・OutputStream) と、java.nio.file パッケージの Path・Files の両方が問われます。メソッドが「何を返すか」「ファイルがあるとき・ないときにどうなるか (例外か、上書きか)」を正確に覚えることが大切です。

出題項目は「コンソールに対するデータの読み取りと書き込み」「I/O ストリームを使用したファイル・アクセス」「シリアライゼーションを使用したオブジェクトの読み取りと書き込み」「Path インタフェースおよび Files クラスを使用したファイルおよびディレクトリ・パスへのアクセス」「Stream API を使用したファイルアクセス操作」の 5 つです。

コンソールへの入出力

System.out.printf (format も同じ) は、書式を指定して出力します。%s は文字列、%d は整数、%f は小数、%n は改行です。%-5s は幅 5 で左寄せ、%5.2f は幅 5・小数点以下 2 桁で右寄せ、%03d は幅 3 で足りない桁を 0 で埋めます。

Main.java
public class Main {    public static void main(String[] args) {        System.out.printf("[%-5s][%5.2f][%03d]%n", "ab", 3.14159, 7);    }}
ターミナル
java Main
[ab   ][ 3.14][007]

Console は System.console() で取得します。コンソールが使えない環境では null が返ることがあるので、使う前に確認します。readLine() は入力を String で、readPassword() は入力を画面に表示せずに char[] で返します (String ではないので、String 型の変数に代入するとコンパイルエラーです)。

Java
Console console = System.console();if (console != null) {    String name = console.readLine("名前: ");    char[] password = console.readPassword("パスワード: ");    console.printf("%s さん、ようこそ%n", name);}

文字ストリームとバイト・ストリーム

java.io のストリームは 2 系統に分かれます。

・文字ストリーム: Reader・Writer のサブクラス (FileReader・FileWriter・BufferedReader・BufferedWriter など)。文字単位で読み書きする ・バイト・ストリーム: InputStream・OutputStream のサブクラス (FileInputStream・ObjectOutputStream など)。バイト単位で読み書きする

FileWriter をファイル名だけで作ると、既存のファイルの内容は消えて先頭から書き込まれます。第 2 引数に true を渡すと追記になります。BufferedWriter は書き込みをメモリにためておき、close() (または flush()) のときにまとめてファイルに書き込みます。BufferedReader の readLine() は 1 行を改行なしで返し、終わりに達すると null を返します。InputStream の read() は 1 バイトを 0 〜 255 の int で返し、終わりでは -1 を返します。

Main.java
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;​public class Main {    public static void main(String[] args) throws IOException {        try (BufferedWriter w = new BufferedWriter(new FileWriter("memo.txt"))) {            w.write("one");            w.newLine();            w.write("two");        }        try (FileWriter w = new FileWriter("memo.txt", true)) {            w.write("\nthree");        }        try (BufferedReader r = new BufferedReader(new FileReader("memo.txt"))) {            String line;            while ((line = r.readLine()) != null) {                System.out.println(line);            }        }        try (InputStream in = new FileInputStream("memo.txt")) {            System.out.println(in.read());        }    }}
ターミナル
java Main
one
two
three
111

最後の 111 は、先頭の文字 o の文字コードです。

シリアライズ

Serializable を実装したクラスのオブジェクトは、ObjectOutputStream の writeObject でバイト列に変換 (シリアライズ) し、ObjectInputStream の readObject で元に戻せます (デシリアライズ)。主なルールは次のとおりです。

・transient を付けたフィールドと static フィールドは保存されない。復元したオブジェクトの transient フィールドは型の既定値 (null・0 など) になる ・デシリアライズでは、そのクラスのコンストラクタは呼ばれない (Serializable でない親クラスがあれば、その引数なしコンストラクタは呼ばれる) ・フィールドが参照しているオブジェクトもまとめて保存される。その中に Serializable でないものがあると NotSerializableException ・保存時と復元時でクラスの serialVersionUID が違うと InvalidClassException

Main.java
import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;​class User implements Serializable {    private static final long serialVersionUID = 1L;    String name;    transient String password;    int age;​    User(String name, String password, int age) {        this.name = name;        this.password = password;        this.age = age;        System.out.println("コンストラクタ");    }}​public class Main {    public static void main(String[] args) throws Exception {        ByteArrayOutputStream bytes = new ByteArrayOutputStream();        try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {            out.writeObject(new User("sato", "secret", 30));        }        try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {            User u = (User) in.readObject();            System.out.println(u.name + " " + u.password + " " + u.age);        }    }}
ターミナル
java Main
コンストラクタ
sato null 30

「コンストラクタ」は new したときの 1 回だけ出力され、復元のときには出力されません。transient の password は null に戻っています。

Path の操作

Path は、ファイルやディレクトリの場所を表します。Path.of(...) (または Paths.get(...)) で作ります。Path の操作はパスの文字列を組み立てるだけで、ファイルが実際にあるかどうかは確かめません。

・getFileName(): 最後の要素 / getParent(): 最後の要素を除いたパス / getNameCount(): ルートを除いた要素の数 ・normalize(): . (現在のディレクトリ) と .. (1 つ上) を取り除く ・resolve(p): パスをつなげる。p が絶対パスなら p そのものを返す ・relativize(p): 自分から p への相対パスを返す

Main.java
import java.nio.file.Path;​public class Main {    public static void main(String[] args) {        Path p = Path.of("/home/user/docs/../report.txt");        System.out.println(p.getFileName());        System.out.println(p.getParent());        System.out.println(p.getNameCount());        System.out.println(p.normalize());​        Path base = Path.of("/home/user");        System.out.println(base.resolve("img/a.png"));        System.out.println(base.relativize(Path.of("/home/user/img/a.png")));        System.out.println(base.resolve("/etc/hosts"));    }}
ターミナル
java Main
report.txt
/home/user/docs/..
5
/home/user/report.txt
/home/user/img/a.png
img/a.png
/etc/hosts

getParent() は .. を解決せずに、文字どおり最後の要素を除くだけです。.. も要素の 1 つとして数えられるので、getNameCount() は 5 になります (この例は macOS・Linux の実行結果です。Windows では区切りが \ になります)。

Files によるファイル操作

Files クラスの static メソッドで、ファイルやディレクトリを操作します。ファイルの有無による動きの違いが、よく問われます。

・createDirectory: 親ディレクトリがないと例外。createDirectories: 途中の親ディレクトリもまとめて作る ・copy・move: コピー先・移動先にファイルがあると FileAlreadyExistsException。StandardCopyOption.REPLACE_EXISTING を指定すると上書きする ・delete: ファイルがないと NoSuchFileException。deleteIfExists: ないときは false を返す ・write・writeString: 既定では上書き。readAllLines・readString: 内容を読む

Main.java
import java.nio.file.Files;import java.nio.file.Path;import java.util.List;​public class Main {    public static void main(String[] args) throws Exception {        Path dir = Path.of("work/sub");        Files.createDirectories(dir);        Path a = dir.resolve("a.txt");        Files.write(a, List.of("alpha", "beta"));        Path b = dir.resolve("b.txt");        Files.copy(a, b);        System.out.println(Files.readAllLines(b));        System.out.println(Files.size(a) + " " + Files.exists(b));        System.out.println(Files.deleteIfExists(Path.of("none.txt")));        Files.copy(a, b);    }}
ターミナル
java Main
[alpha, beta]
11 true
false

実行時に例外が発生: FileAlreadyExistsException

Files.write(パス, 行のリスト) は各要素の後ろに改行を付けて書くので、alpha (5) + 改行 + beta (4) + 改行で 11 バイトです。

Files のストリーム操作

Files には、ファイルやディレクトリを Stream として扱うメソッドがあります。

・Files.lines(パス): ファイルの各行を要素とする Stream<String> ・Files.list(ディレクトリ): ディレクトリの直下の要素だけ (サブディレクトリの中は含まない) ・Files.walk(起点): 起点のディレクトリ自身を含めて、その下を深さ優先でたどる。第 2 引数で深さを制限できる ・Files.find(起点, 深さ, 条件): walk しながら条件に合うものだけを返す

これらが返す Stream は、ファイルやディレクトリを開いたままにしています。使い終わったら閉じる必要があるので、try-with-resources で囲むのが基本です。

Main.java
import java.nio.file.Files;import java.nio.file.Path;import java.util.stream.Stream;​public class Main {    public static void main(String[] args) throws Exception {        Path root = Path.of("tree");        Files.createDirectories(root.resolve("a/b"));        Files.writeString(root.resolve("x.txt"), "1\n2\n3\n");        Files.writeString(root.resolve("a/b/y.txt"), "y");​        try (Stream<Path> s = Files.walk(root)) {            s.map(Path::toString).sorted().forEach(System.out::println);        }        try (Stream<Path> s = Files.list(root)) {            System.out.println(s.count());        }        try (Stream<String> lines = Files.lines(root.resolve("x.txt"))) {            System.out.println(lines.mapToInt(Integer::parseInt).sum());        }    }}
ターミナル
java Main
tree
tree/a
tree/a/b
tree/a/b/y.txt
tree/x.txt
2
6

walk の結果には起点の tree 自身が含まれます。list は直下の a と x.txt だけなので 2 です。

試験でよくある引っかけ

  • readPassword の戻り値

    Console の readPassword() は char[] を返します。String ではありません。

  • FileWriter の上書きと追記

    ファイル名だけで作ると既存の内容は消えます。追記するには第 2 引数に true を渡します。

  • transient と static

    どちらもシリアライズされません。復元後の transient フィールドは既定値になります。

  • デシリアライズとコンストラクタ

    Serializable なクラスのコンストラクタは、デシリアライズのときには呼ばれません。

  • Files.copy の上書き

    コピー先があると FileAlreadyExistsException です。上書きするには REPLACE_EXISTING を指定します。

  • walk と list

    walk は起点自身とその下すべて、list は直下の要素だけを返します。

問題で確認する

この分野の問題を、解説つきで読めます (登録不要)。

出典・参考

コード例は、試験の対象バージョンで実際にコンパイル・実行して結果を確認しています。