Directory.Move no funciona (el archivo ya existe)

Tengo la carpeta principal:

c:\test 

Y allí tengo 2 carpetas: Películas y Fotos.

Fotos tiene tres carpetas con archivos con la misma estructura: Gente, Animales y Edificios. Estoy intentando este código:

 Directory.Move(@"c:\test\Movies", @"c:\test\Test"); 

Me sale una excepción:

 File already exists 

Este método moverá el contenido de una carpeta recursivamente y sobrescribirá los archivos existentes.
Debe agregar un manejo de excepciones.
Editar:
Este método se implementa con un ciclo while y una stack en lugar de recursión.

 public static void MoveDirectory(string source, string target) { var stack = new Stack(); stack.Push(new Folders(source, target)); while (stack.Count > 0) { var folders = stack.Pop(); Directory.CreateDirectory(folders.Target); foreach (var file in Directory.GetFiles(folders.Source, "*.*")) { string targetFile = Path.Combine(folders.Target, Path.GetFileName(file)); if (File.Exists(targetFile)) File.Delete(targetFile); File.Move(file, targetFile); } foreach (var folder in Directory.GetDirectories(folders.Source)) { stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder)))); } } Directory.Delete(source, true); } public class Folders { public string Source { get; private set; } public string Target { get; private set; } public Folders(string source, string target) { Source = source; Target = target; } } 

Actualizar:
Esta es una versión más simple con el uso de Directory.EnumerateFiles recursivamente en lugar de usar una stack.
Esto solo funcionará con .net 4 o posterior, para nosotros con una versión anterior de .net change Directory.EnumerateFiles to Directory.GetFiles .

 public static void MoveDirectory(string source, string target) { var sourcePath = source.TrimEnd('\\', ' '); var targetPath = target.TrimEnd('\\', ' '); var files = Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories) .GroupBy(s=> Path.GetDirectoryName(s)); foreach (var folder in files) { var targetFolder = folder.Key.Replace(sourcePath, targetPath); Directory.CreateDirectory(targetFolder); foreach (var file in folder) { var targetFile = Path.Combine(targetFolder, Path.GetFileName(file)); if (File.Exists(targetFile)) File.Delete(targetFile); File.Move(file, targetFile); } } Directory.Delete(source, true); } 

El directorio de destino no debería existir ya: el método Directory.Move crea el directorio de destino por usted.

 ProcessStartInfo p = new ProcessStartInfo("cmd", "/c move \"c:\\test\\Movies\" \"c:\\test\Test\\""); p.WindowStyle = ProcessWindowStyle.Hidden; //hide mode Process.Start(p); 

¿Es seguro para usted eliminar la carpeta de destino antes de copiar nuevos contenidos en ella?

  Directory.Delete(@"c:\test\test"); Directory.Move(@"c:\test\movies",@"c:\test\test"); 

Las 2 razones más comunes por las que Directory.Move podría fallar son, si:

  • Es un volumen diferente (necesitas copiar / borrar)
  • Ya existe (no admite la sobrescritura por defecto)

Aquí está mi solución simple para el segundo problema (sobrescribir):

 public bool MoveDirectory(string sourceDirName, string destDirName, bool overwrite) { if (overwrite && Directory.Exists(destDirName)) { var needRestore = false; var tmpDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); try { Directory.Move(destDirName, tmpDir); needRestore = true; // only if fails Directory.Move(sourceDirName, destDirName); return true; } catch (Exception) { if (needRestore) { Directory.Move(tmpDir, destDirName); } } finally { Directory.Delete(tmpDir, true); } } else { Directory.Move(sourceDirName, destDirName); // Can throw an Exception return true; } return false; }