Rinomina un file in C #


633

Come rinominare un file usando C #?


Odierei aggiungere che qui c'è un problema con tutte le soluzioni, specialmente se si confronta e si sta spostando il file da una posizione a un'altra (directory e nome del file) in quanto 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 no.
Adrian Hum,

Risposte:


967

Dai un'occhiata a System.IO.File.Move , "sposta" il file con un nuovo nome.

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

12
Questa soluzione non funziona quando i nomi dei file differiscono solo in lettere maiuscole. Ad esempio file.txt e File.txt
SepehrM

2
@SepehrM, ho appena ricontrollato e funziona benissimo sulla mia macchina Windows 8.1.
Chris Taylor,

1
@SepehrM, non l'ho testato, ma i campioni che punti per utilizzare FileInfo.Move e non File.Move quindi forse ha qualcosa a che fare con esso?
Chris Taylor,

2
@SepehrM I nomi dei file system di Windows non fanno distinzione tra maiuscole e minuscole. File.txt e file.txt sono trattati con lo stesso nome file. Quindi non mi è chiaro quando dici che la soluzione non funziona. Cosa stai facendo esattamente che non funziona?
Michael,

4
@Michael, il file system non fa distinzione tra maiuscole e minuscole, ma memorizza il nome file nel caso originale immesso dall'utente. Nel caso di SepehrM, stava cercando di cambiare il caso di un file, che per qualche motivo non funzionava. La corrispondenza senza distinzione tra maiuscole e minuscole funzionava. HTH
Chris Taylor,


47

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

Quindi dobbiamo verificare se il file esiste o no.

/* 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

O circondalo con un tentativo di cattura per evitare un'eccezione.


20
stai molto attento con questo approccio ... se la tua directory di destinazione e la tua directory di origine sono uguali e il "newname" è in realtà una versione con distinzione tra maiuscole e minuscole di "oldFileName", eliminerai prima di avere la possibilità di spostare il tuo file.
Adrian Hum,

1
Inoltre, non è possibile controllare l'uguaglianza delle stringhe in quanto esistono diversi modi per rappresentare un singolo percorso di file.
Drew Noakes,

File.Move ha ora un metodo di sovraccarico che ti consente di sovrascrivere il file - File.Move (oldPath, newPath, true)
Ella


34

Aggiungi solo:

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");

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

31
eww ... Usa Path.Combine () invece di assemblare il file.
Adrian Hum,

20
  1. Prima soluzione

    Evita le System.IO.File.Movesoluzioni pubblicate qui (inclusa la risposta contrassegnata). Fallisce sulle reti. Tuttavia, il modello di copia / eliminazione funziona localmente e sulle reti. Segui una delle soluzioni di spostamento, ma sostituiscila invece con Copia. Quindi utilizzare File.Delete per eliminare il file originale.

    È possibile creare un metodo Rinomina per semplificarlo.

  2. Facilità d'uso

    Utilizzare l'assembly VB in C #. Aggiungi riferimento a Microsoft.VisualBasic

    Quindi per rinominare il file:

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

    Entrambi sono stringhe. Si noti che myfile ha il percorso completo. newName no. Per esempio:

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

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


8
solo così sai, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile chiama File.Move. Altro grazie alla normalizzazione del file originale e all'esecuzione di ulteriori controlli degli errori sugli argomenti, ad es. il file esiste, il nome del file non è null ecc. quindi chiama File.Move.
Chris Taylor,

A meno che Copy () non copi tutti i flussi di file, cosa che presumo non lo faccia, starei lontano dall'uso di cancella / copia. Suppongo che Move (), almeno quando si trova sullo stesso file system, sia semplicemente una ridenominazione e quindi tutti i flussi di file verranno mantenuti.
Nickdu

"fallisce sulla rete" quindi copierai ed eliminerai che in realtà è download e upload, solo per comodità del time-code ... Che tipo di rete? Cartella condivisa di Windows ( smb), ftp, ssho qualsiasi altra cosa sono tutte dotate di comandi / primitive per il file in movimento / rinomina a meno che non consentito (ad esempio sola lettura).
Meow Cat 2012

16

Puoi copiarlo come nuovo file e quindi eliminare quello vecchio usando la System.IO.Fileclasse:

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

4
Nota per chiunque legga questo: questo è un anti-pattern, il file potrebbe essere cancellato o rinominato da un altro processo o dal sistema operativo tra il controllo per verificare se esiste e la tua chiamata a Copia. Devi invece usare un tentativo di cattura.
user9993

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

Sto elaborando migliaia di file e ho avuto l'impressione che Copia / Elimina sia più veloce di Sposta.
Roberto,

Come qualcuno potrebbe venire con una simile idea. Più veloce o almeno non stai uccidendo il disco. Dicendo "rinomina" nella domanda dovrebbe significare rinominare localmente, che ovviamente non comporta alcun movimento tra le partizioni.
Meow Cat 2012,

con File.Move mi sono imbattuto in UnauthorizedAccessException, ma questa sequenza di Copia ed Elimina ha funzionato. Grazie!
Oliver Konig,

6

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

Esistono altri modi per lavorare da questo codice per fare rinominazioni più elaborate, ma la mia intenzione principale era mostrare come usare File.Move per rinominare in batch. Questo ha funzionato contro 335 file PDF in 180 directory quando l'ho eseguito sul mio laptop. Questo è lo stimolo 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 a parte il punto, su una domanda ha risposto esattamente al punto 3 anni fa.
Nyerguds,

2
È un esempio valido. Overkill forse ma non a parte il punto. +1
Adam,

1
@Adam: è un'implementazione molto specifica esattamente della risposta che era già stata data tre anni prima, su una domanda che non riguardava nessuna implementazione specifica in primo luogo. Non vedere come sia in qualche modo costruttivo.
Nyerguds,

@Nyerguds quindi abbiamo diverse definizioni di 'accanto al punto', il che non sorprende dal momento che è un termine soggettivo.
Adam,

@Nyerguds se per te è irrilevante, allora va bene. Ad alcune persone piace la verbosità perché li aiuta a trovare implementazioni "reali" del codice "esempio / esempio". Rinomina i file. Com'è accanto al punto è praticamente come ha detto Adam, è soggettivo. Per qualche motivo lo ritieni assolutamente obiettivo. Oh bene, a ciascuno il suo. Grazie per l'input, in entrambi i casi.
MicRoc,

6

Fiduciosamente! sarà utile per te. :)

  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 usare 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);
        }
    }

6

Uso:

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);

5
Se hai intenzione di farlo, suggerirei di verificare che "oldFilePath" esista prima di fare qualsiasi cosa ... altrimenti eliminerai "newFilePath" senza motivo.
John Kroetch,

Compile ( Using System.IO;)?
Peter Mortensen,

3

Nel mio caso, voglio che il nome del file rinominato sia univoco, quindi aggiungo un timbro data-ora al nome. In questo modo, il nome file del registro 'vecchio' è 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"))));
    }
}

2

Sposta sta facendo lo stesso = Copia ed Elimina 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,

No, Sposta sicuramente non copia ed elimina.
Jim Balter

1

Non sono riuscito a trovare l'approccio adatto a me, quindi propongo la mia versione. Naturalmente è necessario input, gestione degli errori.

public void Rename(string filePath, string newFileName)
{
    var newFilePath = Path.Combine(Path.GetDirectoryName(filePath), newFileName + Path.GetExtension(filePath));
    System.IO.File.Move(filePath, newFilePath);
}

1
  public static class ImageRename
    {
        public static void ApplyChanges(string fileUrl,
                                        string temporaryImageName, 
                                        string permanentImageName)
        {               
                var currentFileName = Path.Combine(fileUrl, 
                                                   temporaryImageName);

                if (!File.Exists(currentFileName))
                    throw new FileNotFoundException();

                var extention = Path.GetExtension(temporaryImageName);
                var newFileName = Path.Combine(fileUrl, 
                                            $"{permanentImageName}
                                              {extention}");

                if (File.Exists(newFileName))
                    File.Delete(newFileName);

                File.Move(currentFileName, newFileName);               
        }
    }

0

Ho riscontrato un caso in cui ho dovuto rinominare il file all'interno del gestore eventi, che si stava innescando per qualsiasi modifica del file, incluso rinominare, e per saltare per sempre la ridenominazione del file che ho dovuto rinominare, con:

  1. Fare la sua copia
  2. Rimozione dell'originale
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

Nel caso in cui qualcuno, avrà tale scenario;)


0
int rename(const char * oldname, const char * newname);

La funzione rename () è definita nel file di intestazione stdio.h. Rinomina un file o una directory da oldname a newname. L'operazione di ridenominazione è la stessa di sposta, quindi puoi anche usare questa funzione per spostare un file.


Benvenuto. Questa domanda riguarda la ridenominazione di un file usando il linguaggio C #. Non sono sicuro di come sia utile sottolineare qualcosa dalla libreria standard di C (non C #).
Jeff Dammeyer

-10

Quando C # non ha alcune funzionalità, utilizzo 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);
    }
}

20
C # ha assolutamente la possibilità di rinominare i file.
Andrew Barber,

76
Sono senza parole
Chris McGrath,

Grazie, questo è esattamente quello che volevo. Può cambiare il nome di sé su un file eseguibile.
Jake,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.