「フォルダを作成、削除、移動(名前の変更)する」で説明したように、フォルダの移動はDirectory.Moveメソッドでできます。しかし、残念ながら"Directory.Copy"のようなメソッドはありませんので、Directoryクラスでフォルダをコピーすることはできません。ここでは、フォルダをコピーする方法を紹介します。
「ファイルをコピー、移動(名前の変更)、削除する」で紹介しているFile.Copyメソッドを使ってファイルを1つずつコピーする方法が考えられます。この方法で、以下のようなメソッドを作ってみました。このメソッドでは、属性もコピーしています。
''' <summary> ''' ディレクトリをコピーする ''' </summary> ''' <param name="sourceDirName">コピーするディレクトリ</param> ''' <param name="destDirName">コピー先のディレクトリ</param> Public Shared Sub CopyDirectory( _ ByVal sourceDirName As String, _ ByVal destDirName As String) 'コピー先のディレクトリがないときは作る If Not System.IO.Directory.Exists(destDirName) Then System.IO.Directory.CreateDirectory(destDirName) '属性もコピー System.IO.File.SetAttributes(destDirName, _ System.IO.File.GetAttributes(sourceDirName)) End If 'コピー先のディレクトリ名の末尾に"\"をつける If destDirName.Chars((destDirName.Length - 1)) <> _ System.IO.Path.DirectorySeparatorChar Then destDirName = destDirName + System.IO.Path.DirectorySeparatorChar End If 'コピー元のディレクトリにあるファイルをコピー Dim fs As String() = System.IO.Directory.GetFiles(sourceDirName) Dim f As String For Each f In fs System.IO.File.Copy(f, _ destDirName + System.IO.Path.GetFileName(f), True) Next 'コピー元のディレクトリにあるディレクトリをコピー Dim dirs As String() = System.IO.Directory.GetDirectories(sourceDirName) Dim dir As String For Each dir In dirs CopyDirectory(dir, destDirName + System.IO.Path.GetFileName(dir)) Next End Sub
/// <summary> /// ディレクトリをコピーする /// </summary> /// <param name="sourceDirName">コピーするディレクトリ</param> /// <param name="destDirName">コピー先のディレクトリ</param> public static void CopyDirectory( string sourceDirName, string destDirName) { //コピー先のディレクトリがないときは作る if (!System.IO.Directory.Exists(destDirName)) { System.IO.Directory.CreateDirectory(destDirName); //属性もコピー System.IO.File.SetAttributes(destDirName, System.IO.File.GetAttributes(sourceDirName)); } //コピー先のディレクトリ名の末尾に"\"をつける if (destDirName[destDirName.Length - 1] != System.IO.Path.DirectorySeparatorChar) destDirName = destDirName + System.IO.Path.DirectorySeparatorChar; //コピー元のディレクトリにあるファイルをコピー string[] files = System.IO.Directory.GetFiles(sourceDirName); foreach (string file in files) System.IO.File.Copy(file, destDirName + System.IO.Path.GetFileName(file), true); //コピー元のディレクトリにあるディレクトリについて、再帰的に呼び出す string[] dirs = System.IO.Directory.GetDirectories(sourceDirName); foreach (string dir in dirs) CopyDirectory(dir, destDirName + System.IO.Path.GetFileName(dir)); }
.NET Framework 2.0以降のVB.NETでは、My.Computer.FileSystem.CopyDirectoryメソッドを使ってフォルダのコピーを行うことができます。C#でも「Microsoft.VisualBasic.dll」を参照設定に追加すれば、FileSystem.CopyDirectoryメソッドで同じことができます。
FileSystem.CopyDirectoryメソッドの使い方は、「フォルダを作成、削除、移動(名前の変更)する」で紹介しているFileSystem.MoveDirectoryメソッドとほぼ同じです。引数にUIOptionが指定されていない場合は、上記のFile.Copyメソッドで1つずつコピーする方法と同じような方法でフォルダをコピーします。引数にUIOptionが指定されている時は、SHFileOperation関数を使用してフォルダをコピーします。そのため、エクスプローラでフォルダをコピーしたときのようにユーザーインターフェイス(「コピーしています...」ダイアログ)を表示させてコピーの進行状況を表示し、途中でユーザーがキャンセルすることもできます。
下の例では、フォルダ"C:\A"を"C:\B"にコピーしています。ユーザーインターフェイスを表示するためにUIOption.AllDialogsを、ユーザーがキャンセルしても例外OperationCanceledExceptionをスローしないようにUICancelOption.DoNothingを指定しています(デフォルトでは、例外がスローされます)。
'ディレクトリ"C:\A"を"C:\B"にコピーする
My.Computer.FileSystem.CopyDirectory("C:\A", "C:\B", _
FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)
//参照にMicrosoft.VisualBasic.dllが追加されている必要がある
//ディレクトリ"C:\A"を"C:\B"にコピーする
Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(
"C:\\A", "C:\\B",
Microsoft.VisualBasic.FileIO.UIOption.AllDialogs,
Microsoft.VisualBasic.FileIO.UICancelOption.DoNothing);
(この記事は掲示板での質問を基に作成しました。)