C#でディレクトリ(フォルダー)を削除する方法について紹介します。
ディレクトリの削除には、System.IO名前空間のDirectoryInfoクラスのDeleteメソッドを使用するか、DirectoryクラスのDelete静的メソッドを使用します。
目次
DirectoryInfoクラスのDeleteメソッドで削除
DirectoryInfoクラスのDeleteメソッドの構文は次のようになります。
1 |
public void Delete (); |
1 |
public void Delete (bool recursive); |
引数を取らないメソッドは空のディレクトリを削除するときに使用します。
引数にbool型のrecursiveを取るメソッドは、ディレクトリの中に含まれるサブディレクトリとファイルを合わせて削除するかどうかを指定して使用します。trueを指定するとサブディレクトリとファイルを削除します。falseを指定すると引数を指定しないDeleteメソッドと同様にディレクトリが空の場合に削除します。
DirectoryInfo.Deleteメソッドの使用例
以下にDeleteメソッドの使用例を示します。
1 2 3 4 5 6 |
// ディレクトリパス string path = @"C:\Test\NewDir"; // DirectoryInfoのインスタンスを生成する DirectoryInfo di = new DirectoryInfo(path); // ディレクトリを削除する di.Delete(); |
上記の例では以下の記事「ディレクトリ(フォルダー)を作成する」で作成するディレクトリのC:\Test\NewDirディレクトリを削除しています。
サブディレクトリファイルを含めて削除する場合は引数にtrueを指定します。
1 2 3 4 5 6 |
// ディレクトリパス string path = @"C:\Test\NewDir"; // DirectoryInfoのインスタンスを生成する DirectoryInfo di = new DirectoryInfo(path); // サブディレクトリとファイルを含めてディレクトリを削除する di.Delete(true); |
DirectoryInfoクラスの引数を指定しないDeleteメソッド、または引数recursiveにfalseを指定したDeleteメソッドの実行時に、空でないディレクトリを削除しようとすると「System.IO.IOException: ‘ディレクトリが空ではありません。’」という例外が発生します。
DirectoryクラスのDelete静的メソッドで削除
DirectoryクラスのDelete静的メソッドの構文は次のようになります。
1 |
public static void Delete (string path); |
1 |
public static void Delete (string path, bool recursive); |
DirectoryクラスのDelete静的メソッドもDirectoryInfoクラスのDeleteメソッドと同じように使用します。
引数のpathには削除するディレクトリのパスを指定します。
bool型の引数recursiveにはディレクトリの中に含まれるサブディレクトリとファイルを合わせて削除するかどうかを指定します。
Directory.Delete静的メソッドの使用例
以下にDelete静的メソッドの使用例を示します。
1 2 3 4 |
// ディレクトリパス string path = @"C:\Test\NewDir"; // ディレクトリを削除する Directory.Delete(path); |
1 2 3 4 |
// ディレクトリパス string path = @"C:\Test\NewDir"; // サブディレクトリとファイルを含めてディレクトリを削除する Directory.Delete(path, true); |
DirectoryクラスのDelete静的メソッドも引数recursiveを指定しない場合、および引数recursiveにfalseを指定した場合に削除対象のディレクトリが空でなければ例外(System.IO.IOException)が発生します。
DirectoryInfoクラスのDeleteメソッド、DirectoryクラスのDelete静的メソッドともに、ディレクトリ以下のサブディレクトリ、ファイルの中に読み取り専用属性が設定されているものがあると「System.UnauthorizedAccessException: パス ‘○○○○○’ へのアクセスが拒否されました。」という例外が発生してしまいます。
これを回避するためには削除するディレクトリとディレクトリ内のすべてのサブディレクトリ、およびファイルの読み取り専用属性を変更する必要があります。
以下に読み取り専用を変更するコードの例を示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// ディレクトリ以下のすべてのファイル、ディレクトリの読み取り専用属性を変更 private void ChangeReadonlyAttribute(DirectoryInfo di) { // 削除するディレクトリの属性を変更 if ((di.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { di.Attributes = FileAttributes.Normal; } // ディレクトリ内のすべてのファイルの属性を変更 foreach (FileInfo fi in di.GetFiles()) { if ((fi.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { fi.Attributes = FileAttributes.Normal; } } // サブディレクトリがある場合はサブディレクトリの属性を自メソッドを呼び出して再帰的に変更 foreach (DirectoryInfo d in di.GetDirectories()) { ChangeReadonlyAttribute(d); } } |
上記のメソッドではディレクトリとファイルの属性を参照して、読み取り専用属性がある場合に通常(特別な属性を持たない標準ファイル)に変更しています。このメソッドをディレクトリを削除する処理の前に呼び出してやることで、読み取り専用属性のディレクトリまたはファイルが含まれていてもディレクトリを削除することができます。
サンプルプログラム
Windowsフォームアプリケーションでのプログラムの実装例を記載します。
ユーザーインターフェース
フォームのインターフェースは次のようにします。
ソースコード
サンプルプログラムのフォームには次のようなソースコードを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
using System; using System.Windows.Forms; // System.IOのusingを追加 using System.IO; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // DirectoryInfoクラスのDeleteメソッドで削除 private void button1_Click(object sender, EventArgs e) { try { // ディレクトリパス string path = textBox1.Text; // DirectoryInfoのインスタンスを生成 DirectoryInfo di = new DirectoryInfo(path); // ディレクトリを削除 di.Delete(); // 完了メッセージを表示 MessageBox.Show($"{di.FullName}を削除しました。"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } // DirectoryInfoクラスのDeleteメソッドの引数にrecursiveを指定して削除 private void button2_Click(object sender, EventArgs e) { try { // ディレクトリパス string path = textBox1.Text; // DirectoryInfoのインスタンスを生成 DirectoryInfo di = new DirectoryInfo(path); // ディレクトリ内のサブディレクトリとファイルを含めて削除するかどうか bool recursive = checkBox1.Checked; // ディレクトリを削除 di.Delete(recursive); // 完了メッセージを表示 MessageBox.Show($"{di.FullName}を削除しました。"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } // DirectoryクラスのDelete静的メソッドで削除 private void button3_Click(object sender, EventArgs e) { try { // ディレクトリパス string path = textBox1.Text; // ディレクトリを削除 Directory.Delete(path); // 完了メッセージを表示 MessageBox.Show($"{path}を削除しました。"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } // DirectoryクラスのDelete静的メソッドの引数にrecursiveを指定して削除 private void button4_Click(object sender, EventArgs e) { try { // ディレクトリパス string path = textBox1.Text; // ディレクトリ内のサブディレクトリとファイルを含めて削除するかどうか bool recursive = checkBox1.Checked; // ディレクトリを削除 Directory.Delete(path, recursive); // 完了メッセージを表示 MessageBox.Show($"{path}を削除しました。"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } } |
サンプルの実行
作成したプログラムを実行します。
[button1]がDirectoryInfoクラスのDeleteメソッドの引数を指定しないでディレクトリを削除する処理を実行します。
[button2]がDirectoryInfoクラスのDeleteメソッドの引数にサブディレクトリとファイルを含めて削除するかどうかを指定してディレクトリを削除する処理を実行します。
[button3]がDirectoryクラスのDelete静的メソッドの引数を指定しないでディレクトリを削除する処理を実行します。
[button4]がDirectoryクラスのDelete静的メソッドの引数にサブディレクトリとファイルを含めて削除するかどうかを指定してディレクトリを削除する処理を実行します。
DドライブにWork > DeletionDirectorySample > MyDirの順にディレクトリを作成します。
パスのテキストボックスに「D:\Work\DeletionDirectorySample\MyDir」を入力します。
[button1]をクリックします。
メッセージが表示され、MyDirディレクトリが削除されます。
DeletionDirectorySampleディレクトリの中にMyDirディレクトリを再度作成し、MyDirディレクトリの中にChildDirディレクトリを作成します。
[button1]をクリックします。
サブディレクトリが存在するので例外が発生してメッセージが表示され、MyDirディレクトリが削除されません。
[button2]をクリックします。
[button1]の時と同様に、サブディレクトリが存在するので例外が発生してメッセージが表示され、MyDirディレクトリが削除されません。
サブディレクトリおよびファイルを含めるのチェックボックスをチェックONにします。
[button2]をクリックします。
メッセージが表示され、MyDirディレクトリが削除されます。
[button3]と[button4]については、[button1]と[button2]の場合と同じ動作となりますので省略しますが、皆さんはよかったら試してみてください。