CodeGym /コース /JAVA 25 SELF /ディレクトリの操作:作成、削除、内容の一覧表示

ディレクトリの操作:作成、削除、内容の一覧表示

JAVA 25 SELF
レベル 35, レッスン 4
使用可能

1. ディレクトリの作成

ディレクトリ(フォルダとも呼ばれます)は単なるファイルの入れ物ではなく、ディスク上のデータ整理の基盤です。アプリケーションでは入出力データ、ログ、一時ファイルなどのために、常にディレクトリを作成します。現代的な API の java.nio.file を使えば、簡潔かつクロスプラットフォームに扱えます。

ここでは、Files、Path、Paths クラスを使って、ディレクトリの作成・削除・内容の一覧取得を見ていきます。

Files.createDirectory(path)

指定したパスに 1 つ のディレクトリを作成します。親ディレクトリが存在しない場合は、例外が送出されます。

import java.nio.file.*;

public class DirectoryDemo {
    public static void main(String[] args) throws Exception {
        Path dir = Paths.get("testDir");
        if (!Files.exists(dir)) {
            Files.createDirectory(dir);
            System.out.println("ディレクトリを作成しました: " + dir.toAbsolutePath());
        } else {
            System.out.println("ディレクトリは既に存在します: " + dir.toAbsolutePath());
        }
    }
}

既に存在するディレクトリを作成しようとすると、FileAlreadyExistsException が発生します。

Files.createDirectories(path)

ディレクトリの階層全体を作成します。途中のディレクトリが存在しない場合は自動的に作成されます。チェーンの一部が既に存在していてもエラーにはなりません。

Path nestedDir = Paths.get("parent/child/grandchild");
Files.createDirectories(nestedDir);
System.out.println("ディレクトリ階層を作成しました: " + nestedDir.toAbsolutePath());

例えるなら、家だけでなく、まだ存在しないなら玄関や通りまでまとめて Java に作らせるイメージです。

よくある例:プロジェクト用の構成を作る

たとえば、レポートをフォルダ output/reports/2024 に保存したいとします。各ディレクトリを手作業で確認するのではなく、createDirectories を使いましょう。

Path reportsPath = Paths.get("output/reports/2024");
Files.createDirectories(reportsPath);

何が既にあり、何を作る必要があるかは Java が判断してくれます。

2. ファイルとディレクトリの削除

Files.delete(path)

ファイルまたは 空の ディレクトリを削除します。ディレクトリが空でない場合は、DirectoryNotEmptyException が送出されます。

Path dir = Paths.get("testDir");
try {
    Files.delete(dir);
    System.out.println("ディレクトリを削除しました: " + dir.toAbsolutePath());
} catch (DirectoryNotEmptyException e) {
    System.out.println("削除できません: ディレクトリが空ではありません!");
}

Files.deleteIfExists(path)

delete と同様に動作しますが、対象が存在しない場合はエラーを投げません。何かを削除できた場合は true、対象がなかった場合は false を返します。

Path file = Paths.get("output/reports/2024/report.txt");
if (Files.deleteIfExists(file)) {
    System.out.println("ファイルを削除しました。");
} else {
    System.out.println("ファイルが見つかりません。何も削除していません。");
}

空でないディレクトリを削除するには?

空でないディレクトリはそのままでは削除できません。まず中身(ファイルとサブディレクトリ)をすべて削除し、その後でディレクトリ本体を削除します。これは再帰的に処理します。例えば、Files.walkFileTree を使います:

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class DeleteDirectoryRecursively {
    public static void main(String[] args) throws IOException {
        Path dir = Paths.get("parent");
        if (Files.exists(dir)) {
            Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Files.delete(file);
                    return FileVisitResult.CONTINUE;
                }
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Files.delete(dir);
                    return FileVisitResult.CONTINUE;
                }
            });
            System.out.println("ディレクトリとその中身をすべて削除しました。");
        }
    }
}

始めたばかりの方は、このコードに怖気づく必要はありません — 後ほど walkFileTree を詳しく解説します。

3. ディレクトリ内容の一覧表示

Files.list(path)

Stream<Path>(パスのストリーム)を返します。Stream API でディレクトリの内容を処理できます。各要素はファイルまたはサブディレクトリです(再帰ではありません!)。

Path dir = Paths.get("output/reports");
if (Files.exists(dir) && Files.isDirectory(dir)) {
    try (var stream = Files.list(dir)) {
        stream.forEach(path -> System.out.println(path.getFileName()));
    }
}

重要なポイント: ストリームは必ずクローズする必要があるため、try‑with‑resources を使用します。

例: ファイル名とサブディレクトリ名を出力する

Path reports2024 = Paths.get("output/reports/2024");
try (var stream = Files.list(reports2024)) {
    stream.forEach(path -> {
        String type = Files.isDirectory(path) ? "ディレクトリ" : "ファイル";
        System.out.println(path.getFileName() + " — " + type);
    });
}

コレクションとしてファイル一覧を取得する

List<Path> files = Files.list(reports2024)
    .filter(Files::isRegularFile)
    .toList();

System.out.println("ディレクトリ内のファイル:");
files.forEach(System.out::println);

重要: Files.list(path) は現在のディレクトリ(最上位)の内容だけを返します。再帰的に走査する場合は Files.walk(path) を使用してください。

4. 実践: ミニファイルマネージャー

ユーティリティはディレクトリ mydata/logs とファイル log1.txt を作成し、フォルダの内容を表示してから、すべてを削除します。

import java.nio.file.*;
import java.io.IOException;

public class MiniFileManager {
    public static void main(String[] args) throws IOException {
        Path logsDir = Paths.get("mydata/logs");
        Files.createDirectories(logsDir);

        Path logFile = logsDir.resolve("log1.txt");
        Files.writeString(logFile, "こんにちは、ログ!");

        System.out.println("ディレクトリ " + logsDir + " の内容:");
        try (var stream = Files.list(logsDir)) {
            stream.forEach(path -> System.out.println(" - " + path.getFileName()));
        }

        Files.deleteIfExists(logFile);
        Files.deleteIfExists(logsDir);
        System.out.println("ファイルとディレクトリを削除しました。");
    }
}

コードに関する補足:

  • Files.createDirectories は階層全体の作成を保証します。
  • resolve — パスにファイル名を付け足す便利な方法です。
  • Files.list のストリームは try‑with‑resources でクローズします — 特に Windows では重要です。

5. 注意点とコツ

存在確認

作成や削除の前に、そのパスが存在するかを確認しておくと便利です:

if (!Files.exists(path)) {
    Files.createDirectory(path);
}

アクセス権

プログラムに作成/削除の権限がない場合は AccessDeniedException になります。例えば、一般ユーザーがディスクのルートにフォルダを作成しようとすると、たいていは失敗します。

空のディレクトリ/空でないディレクトリ

削除できるのは空のディレクトリ(Files.delete)だけです。中身ごと削除するには、再帰的な走査(walkFileTree)を使用します。

クロスプラットフォーム性

API java.nio.file は主要な OS で正しく動作し、パス区切り文字も考慮されます。パスの構築には、文字列を連結するのではなく、Paths.get と Path.resolve を使いましょう。

シンボリックリンク

基本的な用途では気にしなくても構いませんが、通常のファイルでもディレクトリでもない「変わった」エントリに出会ったら、それはシンボリックリンクかもしれません。高度な講義で改めて取り上げます。

6. ディレクトリ操作でよくあるミス

ミス 1: 空でないディレクトリを単純に Files.delete(path) で削除しようとする。 Java は DirectoryNotEmptyException を投げます。まず中身を削除してから本体を削除します。

ミス 2: Files.list() のストリームを閉じ忘れる。 try‑with‑resources を使わないとストリームが開いたままになり、Windows ではフォルダ削除時にエラーになる可能性があります。

ミス 3: 親ディレクトリの存在確認をせずに作成する。 Files.createDirectory を parent/child のようなパスに対して呼び出し、parent が存在しないと、NoSuchFileException になります。Files.createDirectories を使用しましょう。

ミス 4: 不要なのに絶対パスを使う。 プロジェクト内では相対パスを優先しましょう — その方がコードは移植しやすくなります。

ミス 5: IOException を処理しない。 どのファイルシステム操作も失敗し得ます。try-catch で包むか、上位にスローしてください。

ミス 6: 権限のない場所で作成/削除しようとする。 この場合は AccessDeniedException になります。実行コンテキストとアクセス権を確認してください。

1
タスク
JAVA 25 SELF, レベル 35, レッスン 4
ロック未解除
レポートを整理する: 年次フォルダ 📂
レポートを整理する: 年次フォルダ 📂
1
タスク
JAVA 25 SELF, レベル 35, レッスン 4
ロック未解除
ゲームアセットストレージのインベントリ 📦
ゲームアセットストレージのインベントリ 📦
1
アンケート/クイズ
ファイル操作、レベル 35、レッスン 4
使用不可
ファイル操作
ファイル操作
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION