2010-07-10 3 views
451

Come rinominare un file utilizzando C#?Rinomina un file in C#

+0

Non vorrei aggiungere che c'è un problema qui tutte le soluzioni qui, specialmente se si fa confronta e si sposta il file da una posizione ad un altro (directory e nome file) nella misura in cui si dovrebbe essere consapevoli che un volume potrebbe essere un punto di giunzione ... quindi se newname è q: \ SomeJunctionDirectory \ hello.txt e il vecchio nome è c: \ TargetOfJunctionPoint \ hello. txt ... i file sono gli stessi ma i nomi non lo sono. –

risposta

688

Dai uno sguardo allo System.IO.File.Move, "sposta" il file su un nuovo nome.

System.IO.File.Move("oldfilename", "newfilename"); 
+9

Questa soluzione non funziona quando i nomi dei file differiscono solo nel caso delle lettere. Ad esempio file.txt e File.txt – SepehrM

+2

@SepehrM, ho appena controllato e funziona correttamente sul mio computer Windows 8.1. –

+0

Non sono sicuro del motivo per cui ciò accade, ma dai un'occhiata a questi post: http://stackoverflow.com/questions/8152731/file-or-folder-rename-to-lower-case-in-c-sharp-using -directoryinfo-fileinfo-move e http://www.codeproject.com/Tips/365773/Rename-a-directory-or-file-name-to-lower-case-with – SepehrM

100
System.IO.File.Move(oldNameFullPath, newNameFullPath); 
36

È possibile utilizzare File.Move per farlo.

-11

Quando C# non ha alcuna funzione, utilizzare C++ o C:

public partial class Program 
{ 
    [DllImport("msvcrt", CallingConvention = CallingConvention.Cdecl, SetLastError = true)] 
    public static extern int rename(
      [MarshalAs(UnmanagedType.LPStr)] 
      string oldpath, 
      [MarshalAs(UnmanagedType.LPStr)] 
      string newpath); 

    static void FileRename() 
    { 
     while (true) 
     { 
      Console.Clear(); 
      Console.Write("Enter a folder name: "); 
      string dir = Console.ReadLine().Trim('\\') + "\\"; 
      if (string.IsNullOrWhiteSpace(dir)) 
       break; 
      if (!Directory.Exists(dir)) 
      { 
       Console.WriteLine("{0} does not exist", dir); 
       continue; 
      } 
      string[] files = Directory.GetFiles(dir, "*.mp3"); 

      for (int i = 0; i < files.Length; i++) 
      { 
       string oldName = Path.GetFileName(files[i]); 
       int pos = oldName.IndexOfAny(new char[] { '0', '1', '2' }); 
       if (pos == 0) 
        continue; 

       string newName = oldName.Substring(pos); 
       int res = rename(files[i], dir + newName); 
      } 
     } 
     Console.WriteLine("\n\t\tPress any key to go to main menu\n"); 
     Console.ReadKey(true); 
    } 
} 
+18

C# ha assolutamente la capacità di rinominare i file. –

+67

Sono senza parole –

4

NOTA: In questo codice di esempio apriamo una directory e cercare i file PDF con aperto e parentesi chiusa nella nome del file. Puoi controllare e sostituire qualsiasi carattere nel nome che ti piace o semplicemente specificare un nuovo nome usando le funzioni di sostituzione.

Esistono altri modi per lavorare con questo codice per eseguire ridenominazioni più complesse, ma la mia intenzione principale era mostrare come utilizzare File.Move per rinominare un batch. Questo ha funzionato contro 335 file PDF in 180 directory quando l'ho eseguito sul mio portatile. Questo è un impulso del codice del momento e ci sono modi più elaborati per farlo.

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace BatchRenamer 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var dirnames = Directory.GetDirectories(@"C:\the full directory path of files to rename goes here"); 

      int i = 0; 

      try 
      { 
       foreach (var dir in dirnames) 
       { 
        var fnames = Directory.GetFiles(dir, "*.pdf").Select(Path.GetFileName); 

        DirectoryInfo d = new DirectoryInfo(dir); 
        FileInfo[] finfo = d.GetFiles("*.pdf"); 

        foreach (var f in fnames) 
        { 
         i++; 
         Console.WriteLine("The number of the file being renamed is: {0}", i); 

         if (!File.Exists(Path.Combine(dir, f.ToString().Replace("(", "").Replace(")", "")))) 
         { 
          File.Move(Path.Combine(dir, f), Path.Combine(dir, f.ToString().Replace("(", "").Replace(")", ""))); 
         } 
         else 
         { 
          Console.WriteLine("The file you are attempting to rename already exists! The file path is {0}.", dir); 
          foreach (FileInfo fi in finfo) 
          { 
           Console.WriteLine("The file modify date is: {0} ", File.GetLastWriteTime(dir)); 
          } 
         } 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
      Console.Read(); 
     } 
    } 
} 
+3

Questo è ... completamente accanto al punto, su una domanda rispondente esattamente al punto 3 anni fa. – Nyerguds

+1

È un esempio valido. Overkill forse ma non accanto al punto. +1 – Adam

+1

@Adam: è un'implementazione molto specifica della risposta esatta che era già stata data tre anni prima, su una domanda che non riguardava alcuna implementazione specifica in primo luogo. Non capisco come sia in alcun modo costruttivo. – Nyerguds

34

Nel metodo File.Move, questo non sovrascriverà il file se già esiste. E genererà un'eccezione.

Quindi dobbiamo controllare se il file esiste o meno.

/* Delete the file if exists, else no exception thrown. */ 

File.Delete(newFileName); // Delete the existing file if exists 
File.Move(oldFileName,newFileName); // Rename the oldFileName into newFileName 

Oppure circondarlo con un tentativo di cattura per evitare un'eccezione.

+11

sii molto attento con questo approccio ... se la tua directory di destinazione e la tua directory di origine sono uguali e il "nuovo nome" è in realtà una versione con maiuscole e minuscole di "oldFileName", eliminerai prima di avere la possibilità di spostare il tuo file . –

+0

Non si può semplicemente controllare le stringhe per l'uguaglianza in quanto vi sono diversi modi di rappresentare un singolo percorso di file. –

23

Basta aggiungere:

namespace System.IO 
{ 
    public static class ExtendedMethod 
    { 
     public static void Rename(this FileInfo fileInfo, string newName) 
     { 
      fileInfo.MoveTo(fileInfo.Directory.FullName + "\\" + newName); 
     } 
    } 
} 

E poi ...

FileInfo file = new FileInfo("c:\test.txt"); 
file.Rename("test2.txt"); 
+1

Non funzionerà se esiste già una sottocartella chiamata newName –

+0

... "\\" + newName + fileInfo.Extension – mac10688

+10

eww ... Usa Path.Combine() invece di assemblare il file. –

4

Usa:

Using System.IO; 

string oldFilePath = @"C:\OldFile.txt"; // Full path of old file 
string newFilePath = @"C:\NewFile.txt"; // Full path of new file 

if (File.Exists(newFilePath)) 
{ 
    File.Delete(newFilePath); 
} 
File.Move(oldFilePath, newFilePath); 
+2

Se hai intenzione di fare questo, ti suggerirei di controllare che il 'oldFilePath' esista prima di fare qualcosa ... altrimenti cancellerai il 'newFilePath' senza motivo. –

+0

Compilare anche ('Using System.IO;')? –

18
  1. Prima soluzione

    evi d soluzioni System.IO.File.Move pubblicate qui (risposta contrassegnata inclusa). Fallisce sulle reti. Tuttavia, copia/elimina modello funziona localmente e su reti. Seguire una delle soluzioni di spostamento, ma sostituirla con Copia. Quindi utilizzare File.Delete per eliminare il file originale.

    È possibile creare un metodo Rinomina per semplificarlo.

  2. Facilità di utilizzo

    Utilizzare il gruppo VB in C#. Aggiungi riferimento Microsoft.VisualBasic

    Quindi rinominare il file:

    Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(myfile, newName);

    Entrambi sono stringhe. Nota che myfile ha il percorso completo. newName non lo fa. Per esempio:

    a = "C:\whatever\a.txt"; 
    b = "b.txt"; 
    Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(a, b); 
    

    La cartella C:\whatever\ ora conterrà b.txt.

+7

solo così sai, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile chiama File.Move. Altri ringraziano normalizzando il file originale e facendo alcuni controlli di errore aggiuntivi sugli argomenti cioè. il file esiste, il nome del file non è nullo ecc. quindi chiama File.Move. –

+0

A meno che Copy() non copi tutti i flussi di file, presumo che non lo faccia, non starei usando l'eliminazione/copia. Presumo Move(), almeno quando si rimane sullo stesso file system, è semplicemente un rinominare e quindi verranno mantenuti tutti i flussi di file. – nickdu

10

È possibile copiare come un nuovo file e quindi eliminare il vecchio utilizzando la classe System.IO.File:

if (File.Exists(oldName)) 
{ 
    File.Copy(oldName, newName, true); 
    File.Delete(oldName); 
} 
+4

Nota per chiunque stia leggendo questo: Questo è un anti-pattern, il file potrebbe essere cancellato o rinominato da un altro processo o dal SO tra il controllo per verificare se esiste e la chiamata a Copia. Devi invece usare un try catch. – user9993

+0

Se il volume è lo stesso, questo è anche un enorme spreco di I/O poiché una mossa effettivamente farebbe un rinominare a livello di informazioni di directory. –

1

Spostare sta facendo lo stesso = copiare e cancellare quello vecchio.

File.Move(@"C:\ScanPDF\Test.pdf", @"C:\BackupPDF\" + string.Format("backup-{0:yyyy-MM-dd_HH:mm:ss}.pdf",DateTime.Now)); 
+1

Vero, se tutto ciò che ti interessa è il risultato finale. Internamente, non così tanto. – Michael

+0

No, lo spostamento sicuramente non copia ed elimina. –

1

Speriamo! ti sarà utile. :)

public static class FileInfoExtensions 
    { 
     /// <summary> 
     /// behavior when new filename is exist. 
     /// </summary> 
     public enum FileExistBehavior 
     { 
      /// <summary> 
      /// None: throw IOException "The destination file already exists." 
      /// </summary> 
      None = 0, 
      /// <summary> 
      /// Replace: replace the file in the destination. 
      /// </summary> 
      Replace = 1, 
      /// <summary> 
      /// Skip: skip this file. 
      /// </summary> 
      Skip = 2, 
      /// <summary> 
      /// Rename: rename the file. (like a window behavior) 
      /// </summary> 
      Rename = 3 
     } 
     /// <summary> 
     /// Rename the file. 
     /// </summary> 
     /// <param name="fileInfo">the target file.</param> 
     /// <param name="newFileName">new filename with extension.</param> 
     /// <param name="fileExistBehavior">behavior when new filename is exist.</param> 
     public static void Rename(this System.IO.FileInfo fileInfo, string newFileName, FileExistBehavior fileExistBehavior = FileExistBehavior.None) 
     { 
      string newFileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(newFileName); 
      string newFileNameExtension = System.IO.Path.GetExtension(newFileName); 
      string newFilePath = System.IO.Path.Combine(fileInfo.Directory.FullName, newFileName); 

      if (System.IO.File.Exists(newFilePath)) 
      { 
       switch (fileExistBehavior) 
       { 
        case FileExistBehavior.None: 
         throw new System.IO.IOException("The destination file already exists."); 
        case FileExistBehavior.Replace: 
         System.IO.File.Delete(newFilePath); 
         break; 
        case FileExistBehavior.Rename: 
         int dupplicate_count = 0; 
         string newFileNameWithDupplicateIndex; 
         string newFilePathWithDupplicateIndex; 
         do 
         { 
          dupplicate_count++; 
          newFileNameWithDupplicateIndex = newFileNameWithoutExtension + " (" + dupplicate_count + ")" + newFileNameExtension; 
          newFilePathWithDupplicateIndex = System.IO.Path.Combine(fileInfo.Directory.FullName, newFileNameWithDupplicateIndex); 
         } while (System.IO.File.Exists(newFilePathWithDupplicateIndex)); 
         newFilePath = newFilePathWithDupplicateIndex; 
         break; 
        case FileExistBehavior.Skip: 
         return; 
       } 
      } 
      System.IO.File.Move(fileInfo.FullName, newFilePath); 
     } 
    } 

Come per utilizzare questo codice?

class Program 
    { 
     static void Main(string[] args) 
     { 
      string targetFile = System.IO.Path.Combine(@"D://test", "New Text Document.txt"); 
      string newFileName = "Foo.txt"; 

      // full pattern 
      System.IO.FileInfo fileInfo = new System.IO.FileInfo(targetFile); 
      fileInfo.Rename(newFileName); 

      // or short form 
      new System.IO.FileInfo(targetFile).Rename(newFileName); 
     } 
    } 
0

Nel mio caso, voglio che il nome del file rinominato per essere unico, così ho aggiungere un timbro datetime al nome. In questo modo, il nome del 'vecchio' di log è sempre unico:

if (File.Exists(clogfile)) 
      { 
       Int64 fileSizeInBytes = new FileInfo(clogfile).Length; 
       if (fileSizeInBytes > 5000000) 
       { 
        string path = Path.GetFullPath(clogfile); 
        string filename = Path.GetFileNameWithoutExtension(clogfile); 
        System.IO.File.Move(clogfile, Path.Combine(path, string.Format("{0}{1}.log", filename, DateTime.Now.ToString("yyyyMMdd_HHmmss")))); 
       } 
      }