「フォルダを作成、削除、移動(名前の変更)する」で説明したように、Directory.Deleteメソッドを使うと、フォルダとそれ以下にあるすべてのファイルとフォルダを削除することができます。しかしこの時、削除するフォルダ以下に読み取り専用属性のファイルやフォルダがあると、例外UnauthorizedAccessExceptionをスローして、削除に失敗します。ここでは、この対策について説明します。
Directory.Deleteメソッドを呼び出す前に、削除するフォルダ以下にあるすべてのファイルとフォルダの読み取り専用属性を外しておくという方法が考えられます。以下に示すDeleteDirectoryメソッドでは、フォルダを削除する前に、そのフォルダ以下のすべてのファイルとフォルダを調べ、読み取り専用属性を外しています。
'Imports System.IO 'がソースファイルの一番上に書かれているものとする ''' <summary> ''' フォルダを根こそぎ削除する(ReadOnlyでも削除) ''' </summary> ''' <param name="dir">削除するフォルダ</param> Public Shared Sub DeleteDirectory(ByVal dir As String) 'DirectoryInfoオブジェクトの作成 Dim di As New DirectoryInfo(dir) 'フォルダ以下のすべてのファイル、フォルダの属性を削除 RemoveReadonlyAttribute(di) 'フォルダを根こそぎ削除 di.Delete(True) End Sub Public Shared Sub RemoveReadonlyAttribute( _ ByVal dirInfo As DirectoryInfo) '基のフォルダの属性を変更 If (dirInfo.Attributes And FileAttributes.ReadOnly) = FileAttributes.ReadOnly Then dirInfo.Attributes = FileAttributes.Normal End If 'フォルダ内のすべてのファイルの属性を変更 Dim fi As FileInfo For Each fi In dirInfo.GetFiles() If (fi.Attributes And FileAttributes.ReadOnly) = FileAttributes.ReadOnly Then fi.Attributes = FileAttributes.Normal End If Next fi 'サブフォルダの属性を回帰的に変更 Dim di As DirectoryInfo For Each di In dirInfo.GetDirectories() RemoveReadonlyAttribute(di) Next di End Sub
//using System.IO; //がソースファイルの一番上に書かれているものとする /// <summary> /// フォルダを根こそぎ削除する(ReadOnlyでも削除) /// </summary> /// <param name="dir">削除するフォルダ</param> public static void DeleteDirectory(string dir) { //DirectoryInfoオブジェクトの作成 DirectoryInfo di = new DirectoryInfo(dir); //フォルダ以下のすべてのファイル、フォルダの属性を削除 RemoveReadonlyAttribute(di); //フォルダを根こそぎ削除 di.Delete(true); } public static void RemoveReadonlyAttribute(DirectoryInfo dirInfo) { //基のフォルダの属性を変更 if ((dirInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) dirInfo.Attributes = FileAttributes.Normal; //フォルダ内のすべてのファイルの属性を変更 foreach (FileInfo fi in dirInfo.GetFiles()) if ((fi.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) fi.Attributes = FileAttributes.Normal; //サブフォルダの属性を回帰的に変更 foreach (DirectoryInfo di in dirInfo.GetDirectories()) RemoveReadonlyAttribute(di); }
.NET Framework 2.0以降のVB.NETでは、My.Computer.FileSystem.DeleteDirectoryメソッドでフォルダを削除することもできます。DeleteDirectoryメソッドでは、引数にUIOption列挙体の値を指定すれば、読み取り専用ファイルがあっても削除します。
このメソッドは、C#でも「Microsoft.VisualBasic.dll」を参照設定に追加すれば、FileSystem.DeleteDirectoryメソッドとして使用することができます。
DeleteDirectoryメソッドにUIOptionを指定して呼び出した時は、それ以上の機能も使用できます。例えばエクスプローラでフォルダを削除したときのように、「削除しています...」ダイアログで進行状況を表示したり、ユーザーが途中で処理をキャンセルできたり、削除したファイルをごみ箱に入れたりすることもできます。詳しくは「フォルダを作成、削除、移動(名前の変更)する」で説明していますので、そちらをご覧ください。
以下に、FileSystem.DeleteDirectoryメソッドを使って"C:\A"フォルダを削除する例を示します。進行状況ダイアログを表示するためにUIOption.AllDialogsを、ごみ箱に入れるためにRecycleOption.SendToRecycleBinを、ユーザーがキャンセルしても例外OperationCanceledExceptionをスローしないようにUICancelOption.DoNothingを指定しています(デフォルトでは、スローされます)。
'ディレクトリ"C:\A"を削除する
My.Computer.FileSystem.DeleteDirectory("C:\A", _
FileIO.UIOption.AllDialogs, _
FileIO.RecycleOption.SendToRecycleBin, _
FileIO.UICancelOption.DoNothing)
//参照にMicrosoft.VisualBasic.dllが追加されている必要がある
//ディレクトリ"C:\A"を削除する
Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(
"C:\\A",
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin,
Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing);
(この記事は掲示板での質問を基に作成しました。)
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。