【Java】フォルダのコピーや削除を安全に行う方法について

Java

はじめに

Javaの実務で、意外とトラブルが多いのが、フォルダ(ディレクトリ)のコピーや削除処理です。フォルダは操作としては単純に見えがちですが、事故が発生しやすい部分でもあります。

  • フォルダごと削除してはいけない場所を消してしまった
  • コピー途中で失敗し、データが中途半端に残った
  • ファイルが使用中で削除できず、バッチが異常終了

今回は、フォルダをコピー・削除する方法についてログとして記載していきたいと思います。

他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:

👉スッキリわかるJava入門 
👉スッキリわかるJava入門 実践編

 

フォルダコピー

java.nio.file パッケージを使ったフォルダコピーの方法について例として挙げていきます。

 

基本方針

  • Files.walk() で再帰的に処理を実施する
  • ファイルとディレクトリを分けて処理を実施する
  • 例外は握りつぶさず、必ずログに残す

 

  • relativize():元フォルダからの相対パスを取得
  • resolve():コピー先に同じ構造を再現
  • COPY_ATTRIBUTES:タイムスタンプなどを保持
package Util;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

public class DirectoryCopyUtil  {

        /**
         * 
         * @param source フォルダコピー元
         * @param target フォルダコピー先
         * @throws IOException
         */
        public static void copyDirectory(Path source, Path target) throws IOException {
        Files.walk(source).forEach(path -> {
            try {
                Path relative = source.relativize(path);
                Path targetPath = target.resolve(relative);

                if (Files.isDirectory(path)) {
                    Files.createDirectories(targetPath);
                } else {
                    Files.copy(
                        path,
                        targetPath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.COPY_ATTRIBUTES
                    );
                }
            } catch (IOException e) {
                throw new RuntimeException("フォルダコピー中にエラーが発生しました: " + path, e);
            }
        });
    }
}

 

フォルダを安全に削除する方法

絶対にやってはいけないこと

フォルダ削除は、コピー以上に慎重さが求められます。相対パスをただただ指定して、全量削除を実施することは、削除してはいけないファイルまで削除してしまう可能性があるため絶対にやってはいけません。削除対象パスのチェック不足は即事故につながります。

Files.delete(Paths.get("/"));

 

安全なフォルダ削除の基本ルール

  • 削除対象パスをログに出す
  • 存在チェックを行う
  • ファイル → フォルダの順で削除
  • 想定外パスは削除しないガードを入れる

 

  • 先にファイル → 最後に親フォルダで削除する
  • 削除対象パスのチェックを実施する
package Util;

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

public class DirectoryDeleteUtil {

    public static void deleteDirectory(Path dir) throws IOException {
        if (!Files.exists(dir)) {
            return;
        }

        // 削除対象パスのチェック
        if (!dir.toAbsolutePath().toString().contains("target")) {
            throw new IllegalArgumentException("削除禁止パスです: " + dir);
        }

        Files.walk(dir)
                .sorted(Comparator.reverseOrder()) // 子→親の順
                .forEach(path -> {
                    try {
                        Files.delete(path);
                    } catch (IOException e) {
                        throw new RuntimeException("削除失敗: " + path, e);
                    }
                });
    }
}

 

実施前にテストすること

実際に削除を動作させる前に、運用としてログを出力するだけの処理を実行して削除対象が間違っていないことを確認することも、有効な事故防止策となります。

Files.walk(dir).forEach(path ->
    System.out.println("[DELETE TARGET] " + path)
);

 

まとめ

フォルダのコピーや削除は、Java実務において避けて通れない処理でありながら、一歩間違えると大きな事故につながる操作でもあります。本記事を参考に、事故に気をつけて実装していきましょう。

 

ドキュメント

【公式ドキュメント】
Java SE Specifications (oracle.com)

 

最後に

Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)

以上、ログになります。
これからも継続していきましょう!!

Javaサーバーサイド関連
シェアする
おすすめIT本
良いコード/悪いコードで学ぶ設計入門

「ITエンジニア本大賞2023」技術書部門で大賞を受賞した本です。
・コードの可読性
・普段意識したほうが良いこと
・リファクタリング考え方
等、普段のコードを設計する際に意識することが書かれています。
コードのあるべき姿に迷ったら一度読んでみると良い本です。

仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん

Dockerって何?となったときに私が最初に読んだ本です。
Dockerがどんな仕組みで動いているのか、コマンドでは何を命令しているのかを理解できるように、イラストを多用して説明しています。

1冊ですべて身につくJavaScript入門講座

「ITエンジニア本大賞2024」技術書部門で大賞を受賞した本です。
私が次に読もうと思っている本なのでおすすめとして挙げておきたいと思います。

コメント

タイトルとURLをコピーしました