2012-12-27 6 views
18

In C# .NET, Come copiare un file in un'altra posizione, sovrascrivendo il file esistente se il file di origine è più recente del file esistente (avere una "Data modificata" successiva) e facendo notazione se il file sorgente è più vecchio?Copia file, sovrascrivi se più recente

+0

è questa finestra o approccio web ?? – user1102001

+0

@ user1102001 windows –

+1

Si potrebbe trovare questo più semplice con un file batch, penso che il comando xcopy rende questo semplice – JMK

risposta

28

È possibile utilizzare la FileInfo class ed è proprietà e metodi:

FileInfo file = new FileInfo(path); 
string destDir = @"C:\SomeDirectory"; 
FileInfo destFile = new FileInfo(Path.Combine(destDir, file.Name)); 
if (destFile.Exists) 
{ 
    if (file.LastWriteTime > destFile.LastWriteTime) 
    { 
     // now you can safely overwrite it 
     file.CopyTo(destFile.FullName, true); 
    } 
} 
7

È possibile utilizzare la classe FileInfo:

FileInfo infoOld = new FileInfo("C:\\old.txt"); 
FileInfo infoNew = new FileInfo("C:\\new.txt"); 

if (infoNew.LastWriteTime > infoOld.LastWriteTime) 
{ 
    File.Copy(source path,destination path, true) ; 
} 
0

In un file batch, questo funzionerà:

XCopy "c:\my directory\source.ext" "c:\my other directory\dest.ext" /d 
+0

sì .. ma probabilmente più complicato dal momento che dobbiamo occuparci degli spazi nel percorso, ecc. –

+1

Abbastanza corretto, penso che i file batch consentano di inserire virgolette singole o doppie attorno a un percorso di file se questo aiuta – JMK

1

Ecco la mia risposta alla risposta: le copie non spostano il contenuto delle cartelle. Se il bersaglio non esiste il codice è più chiaro da leggere. Tecnicamente, la creazione di un fileinfo per un file inesistente avrà un LastWriteTime di DateTime.Min in modo che sia nella copia ma ne diminuisca brevemente la leggibilità. Spero che questo codice testato aiuti qualcuno.

** EDIT: Ho aggiornato la mia fonte per essere molto più flessibile. Poiché si basava su questo thread, ho pubblicato l'aggiornamento qui. Quando si utilizzano maschere i sottodirectory non vengono creati se la sottocartella non contiene file corrispondenti. Sicuramente un gestore di errori più robusto è nel tuo futuro. :)

public void CopyFolderContents(string sourceFolder, string destinationFolder) 
{ 
    CopyFolderContents(sourceFolder, destinationFolder, "*.*", false, false); 
} 

public void CopyFolderContents(string sourceFolder, string destinationFolder, string mask) 
{ 
    CopyFolderContents(sourceFolder, destinationFolder, mask, false, false); 
} 

public void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders) 
{ 
    try 
    { 
     if (!sourceFolder.EndsWith(@"\")){ sourceFolder += @"\"; } 
     if (!destinationFolder.EndsWith(@"\")){ destinationFolder += @"\"; } 

     var exDir = sourceFolder; 
     var dir = new DirectoryInfo(exDir); 
     SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); 

     foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so)) 
     { 
      FileInfo srcFile = new FileInfo(sourceFile); 
      string srcFileName = srcFile.Name; 

      // Create a destination that matches the source structure 
      FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, "")); 

      if (!Directory.Exists(destFile.DirectoryName) && createFolders) 
      { 
       Directory.CreateDirectory(destFile.DirectoryName); 
      } 

      if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists) 
      { 
       File.Copy(srcFile.FullName, destFile.FullName, true); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace); 
    } 
} 
+0

Avviso questo non è un ricorsivo chiamata. (Questo deve essere wikified) –

+1

Questo funziona davvero bene. Suggerirei un ulteriore miglioramento. Aggiungere un test di checksum se il file esiste sia nell'origine che in dest in modo da non copiare il file se sono identici. public String GetChecksum (String filePath) { \t utilizzando (var flusso = new BufferedStream (File.OpenRead (filePath), 1200000)) \t { \t \t SHA256Managed sha = new SHA256Managed(); \t \t byte [] checksum = sha.ComputeHash (flusso); \t \t return BitConverter.ToString (checksum) .Replace ("-", String.Empty); \t} } –

+0

@ChristopherHaws, è un'ottima idea. Lo ripiegherò quando avrò un minuto. :) –

Problemi correlati