3753817_s

C#でフォルダを一括削除する機能を作成していたところ、読み取り専用ファイルや別のプログラムで開いているファイルの例外処理はどうするべきか悩んだので忘備録として残しておきます。


基本的なフォルダの削除


C#でフォルダを削除するにはDirectoryクラスのDeleteメソッドを使います。

フォルダを削除する例外処理なしのサンプルコードは以下の通りです。

// このディレクトリを削除する
string path = "削除したいファイルのパス";
DirectoryInfo directoryInfo = new DirectoryInfo(path);

// このディレクトリ、そのサブディレクトリ、およびすべてのファイルを削除する
directoryInfo.Delete(true);

// ディレクトリが空の場合削除する
directoryInfo.Delete(false);





try catchで例外処理


基本的な例外処理としてまずはtry catchを使って例外処理していきます。

try catchを使った場合、削除するフォルダ内に読み取り専用のファイルがあったりした場合に必ずcatchにとびフォルダは削除されません。

try catchを使う欠点は細かい例外処理ができないことです。エラーがでたら問答無用でcatchに飛んでしまうため、色々といじりたい場合には不向きといった印象です。

サンプルコードは以下の通りです。

// このディレクトリを削除する
string path = "削除したいファイルのパス";
DirectoryInfo directoryInfo = new DirectoryInfo(path);
try{
    // このディレクトリ、そのサブディレクトリ、およびすべてのファイルを削除する
    directoryInfo.Delete(true);
}
catch{
    // エラーならここに入る
}






ファイルの属性を見て例外処理をする


先ほどのtry catchの欠点を埋める方法としてファイルの属性を見て削除するかどうか決める方法があります。

ファイルの属性を見ることで読み取り専用ファイルなら属性を変更して削除するなど細かい設定を行うことができます。

ファイルの属性はFileInfoクラスのAttributesメソッドを使うことで取得できます。

読み取り専用ファイルなら属性を変更して削除するというサンプルプログラムは以下のとおりです。

using System;
using System.IO;

class FileDel
{
    public static void Main()
    {
        try{
            string path = "C:\\Users\\black\\OneDrive\\デスクトップ\\新しいフォルダー";
            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            if (!CheckDeleteDirectory(directoryInfo)){
                // エラー
                return;
            }
            // 削除可能ならフォルダを削除する
            directoryInfo.Delete(true);
        }
        catch{

        }
    }

    // ディレクトリが削除可能か確認する
    private static void CheckDeleteDirectory(DirectoryInfo directoryInfo) {
        foreach (FileInfo fileInfo in directoryInfo.GetFiles()) {
            if ((fileInfo.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly) {
                // 読み取り専用ファイルの場合、読み取り専用属性を解除する
                fileInfo.Attributes = System.IO.FileAttributes.Normal;
            }
        }

        // 再起でサブディレクトリのファイルの属性も変更する
        foreach (DirectoryInfo dirInfo in directoryInfo.GetDirectories()) {
            CheckDeleteDirectory(dirInfo);
        }
    }
}




まとめ

今回はC#のフォルダ、ファイル削除の処理について考えていきました。

単にフォルダやファイルを削除すると言ってもファイルの属性によって処理を変えるなど色々と考えることがあっておもしろいですね。