2015-05-04 15 views
5

Perché File.Move(sourceFileName, destFileName) funziona correttamente quando i file di origine e di destinazione si trovano in partizioni diverse, ma Directory.Move(sourceDirName, destDirName) no? Si getta"Sposta non funziona su tutti i volumi" - Perché? E come superare?

System.IO.IOException: "Source e percorso di destinazione devono avere radici identici mossa non funzionerà su volumi.".

Ho anche provato a creare un'istanza DirectoryInfo e utilizzare il metodo MoveTo(destDirName) ma senza esito positivo.

Mi manca qualcosa? Devo davvero implementare una funzionalità di "spostamento" da solo? (la directory che voglio spostare è molto grande btw).

+1

Il suo perché utilizza questa API native: https://msdn.microsoft. it/it/us/library/windows/desktop/aa365239% 28v = vs.85% 29.aspx *** L'unica avvertenza è che la funzione MoveFile fallirà quando si sposta la directory quando la destinazione si trova su un altro volume. ** * Vorrei 'Process.Start' XCopy e reindirizzare l'output standard per monitorare il processo, specialmente con le directory di grandi dimensioni. –

risposta

2

È possibile anche P/Invoke SHFileOperation che è la stessa funzione di Windows Explorer utilizza per spostare le directory in giro. Effettuerà una vera mossa o ricorsiva-copia-poi-cancella, a seconda dei casi.

Può anche mostrare la stessa UI di avanzamento di Explorer, semplicemente impostando una bandiera.

+1

Puoi indicarmi come farlo? –

+0

@firsttimer: pinvoke.net è ottimo per chiamare le API Win32: http://pinvoke.net/default.aspx/shell32/SHFileOperation.html –

+0

Grazie. Ci sto provando. –

7

È necessario utilizzare la funzione Copy seguita da una rimozione. Come Move funziona solo nella stessa unità. Directory.Move ha una condizione che afferma che:

IO Exception verrà generata se si è tentato di spostare una directory in un volume diverso.

+0

Supponi di non voler modificare la data di creazione della directory. –

+2

Inoltre, il tuo collegamento "Copia' è rotto. C'era una funzione 'Directory.Copy' ad un certo punto? –

3

Un'altra opzione è, per aggiungere un riferimento allo spazio dei nomi Microsoft.VisualBasic e utilizzare il metodo MoveDirectory, che può spostarsi tra i volumi.

Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(sourceDirName, destDirName); 
+0

L'ho provato e non ha conservato la data di creazione, quindi suppongo che faccia ancora una copia/cancella dietro le quinte. –

1

Anche se questa non è una domanda Vb.Net ma ho trovato nessuno ha menzionato questo metodo quindi penso che potrebbe aiutare ... avete solo bisogno di convertirlo in C#, se necessario.

Codice:

My.Computer.FileSystem.MoveDirectory(SrcDir,DestDir) 

Questo funziona su diversi volumi senza soluzione di continuità/per la mia esperienza.

+1

Questa è stata la soluzione più semplice e migliore secondo me. Grazie per la condivisione. –

+0

@MousaAlfhaily sei il benvenuto e sono felice che ti abbia aiutato :) –

1

Sulla base dei messaggi "Copy a directory to a different drive" e "Non-recursive way to get all files in a directory and its subdirectories in Java", ho scritto questo metodo non ricorsivo e funziona benissimo:

public static void Move(string source, string target) 
    { 
     if (!Directory.Exists(source)) 
     { 
      throw new System.IO.DirectoryNotFoundException("Source directory couldn't be found."); 
     } 

     if (Directory.Exists(target)) 
     { 
      throw new System.IO.IOException("Target directory already exists."); 
     } 

     DirectoryInfo sourceInfo = Directory.CreateDirectory(source); 
     DirectoryInfo targetInfo = Directory.CreateDirectory(target); 

     if (sourceInfo.FullName == targetInfo.FullName) 
     { 
      throw new System.IO.IOException("Source and target directories are the same."); 
     } 

     Stack<DirectoryInfo> sourceDirectories = new Stack<DirectoryInfo>(); 
     sourceDirectories.Push(sourceInfo); 

     Stack<DirectoryInfo> targetDirectories = new Stack<DirectoryInfo>(); 
     targetDirectories.Push(targetInfo); 

     while (sourceDirectories.Count > 0) 
     { 
      DirectoryInfo sourceDirectory = sourceDirectories.Pop(); 
      DirectoryInfo targetDirectory = targetDirectories.Pop(); 

      foreach (FileInfo file in sourceDirectory.GetFiles()) 
      { 
       file.CopyTo(Path.Combine(targetDirectory.FullName, file.Name), overwrite: true); 
      } 

      foreach(DirectoryInfo subDirectory in sourceDirectory.GetDirectories()) 
      { 
       sourceDirectories.Push(subDirectory); 
       targetDirectories.Push(targetDirectory.CreateSubdirectory(subDirectory.Name)); 
      } 
     } 

     sourceInfo.Delete(true); 
    } 
Problemi correlati