DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

フォルダをコピーする

フォルダを作成、削除、移動(名前の変更)する」で説明したように、フォルダの移動はDirectory.Moveメソッドでできます。しかし、残念ながら"Directory.Copy"のようなメソッドはありませんので、Directoryクラスでフォルダをコピーすることはできません。ここでは、フォルダをコピーする方法を紹介します。

File.Copyメソッドで1つずつコピーする

ファイルをコピー、移動(名前の変更)、削除する」で紹介しているFile.Copyメソッドを使ってファイルを1つずつコピーする方法が考えられます。この方法で、以下のようなメソッドを作ってみました。このメソッドでは、属性もコピーしています。

VB.NET
コードを隠すコードを選択
''' <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
C#
コードを隠すコードを選択
/// <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));
}

My.Computer.FileSystem.CopyDirectoryメソッドを使用する方法

.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を指定しています(デフォルトでは、例外がスローされます)。

VB.NET
コードを隠すコードを選択
'ディレクトリ"C:\A"を"C:\B"にコピーする
My.Computer.FileSystem.CopyDirectory("C:\A", "C:\B", _
    FileIO.UIOption.AllDialogs, FileIO.UICancelOption.DoNothing)
C#
コードを隠すコードを選択
//参照に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);
  • 履歴:
  • 2007/2/19 My.Computer.FileSystem.CopyDirectoryメソッドを使用する方法を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • Windows Vista以降でUACが有効になっていると、ファイルへの書き込みに失敗する可能性があります。詳しくは、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。