Renommer un fichier en C #

633

Comment renommer un fichier en utilisant C #?

Or
la source
Je détesterais ajouter qu'il y a un problème ici toutes les solutions ici, surtout si vous comparez et déplacez le fichier d'un emplacement à un autre (répertoire ainsi que nom de fichier) dans la mesure où vous devez être conscient qu'un volume peut être un point de jonction ... donc si le nouveau nom est q: \ SomeJunctionDirectory \ hello.txt et l'ancien nom est c: \ TargetOfJunctionPoint \ hello.txt ... les fichiers sont les mêmes mais les noms ne le sont pas.
Adrian Hum

Réponses:

967

Jetez un œil à System.IO.File.Move , "déplacez" le fichier vers un nouveau nom.

System.IO.File.Move("oldfilename", "newfilename");
Chris Taylor
la source
12
Cette solution ne fonctionne pas lorsque les noms de fichiers diffèrent uniquement dans la casse des lettres. Par exemple file.txt et File.txt
SepehrM
2
@SepehrM, je viens de vérifier et cela fonctionne bien sur ma machine Windows 8.1.
Chris Taylor
1
@SepehrM, je ne l'ai pas testé, mais les exemples que vous pointez pour utiliser FileInfo.Move et non File.Move alors peut-être que cela a quelque chose à voir avec cela?
Chris Taylor
2
@SepehrM Les noms de système de fichiers Windows ne respectent pas la casse. File.txt et file.txt sont traités comme le même nom de fichier. Donc, ce n'est pas clair pour moi quand vous dites que la solution ne fonctionne pas. Que faites-vous exactement qui ne fonctionne pas?
Michael
4
@Michael, le système de fichiers est insensible à la casse, mais il stocke le nom de fichier dans le cas d'origine tel qu'il a été entré par l'utilisateur. Dans le cas de SepehrM, il essayait de changer le cas d'un fichier qui, pour une raison quelconque, ne fonctionnait pas. La correspondance insensible à la casse fonctionnait. HTH
Chris Taylor
131
System.IO.File.Move(oldNameFullPath, newNameFullPath);
Aleksandar Vucetic
la source
47

Dans la méthode File.Move, cela n'écrasera pas le fichier s'il existe déjà. Et cela lèvera une exception.

Nous devons donc vérifier si le fichier existe ou non.

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

Ou entourez-le d'une prise d'essai pour éviter une exception.

Mohamed Alikhan
la source
21
soyez très prudent avec cette approche ... si votre répertoire de destination et votre répertoire source sont les mêmes, et que le "nouveau nom" est en fait une version sensible à la casse de "oldFileName", vous supprimerez avant d'avoir la chance de déplacer votre fichier.
Adrian Hum
1
Vous ne pouvez pas simplement vérifier l'égalité des chaînes car il existe plusieurs façons de représenter un chemin de fichier unique.
Drew Noakes
File.Move a maintenant une méthode de surcharge qui vous permet d'écraser le fichier - File.Move (oldPath, newPath, true)
Ella
39

Vous pouvez utiliser File.Movepour le faire.

Franci Penov
la source
34

Ajoutez simplement:

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

Et alors...

FileInfo file = new FileInfo("c:\test.txt");
file.Rename("test2.txt");
Nogro
la source
... "\\" + newName + fileInfo.Extension
mac10688
31
eww ... Utilisez Path.Combine () au lieu d'assembler le fichier.
Adrian Hum
20
  1. Première solution

    Évitez les System.IO.File.Movesolutions affichées ici (réponse marquée incluse). Il échoue sur les réseaux. Cependant, le modèle de copie / suppression fonctionne localement et sur les réseaux. Suivez l'une des solutions de déplacement, mais remplacez-la à la place par Copier. Utilisez ensuite File.Delete pour supprimer le fichier d'origine.

    Vous pouvez créer une méthode Renommer pour la simplifier.

  2. Facilité d'utilisation

    Utilisez l'assemblage VB en C #. Ajouter une référence à Microsoft.VisualBasic

    Puis pour renommer le fichier:

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

    Les deux sont des chaînes. Notez que monfichier a le chemin complet. newName ne le fait pas. Par exemple:

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

    Le C:\whatever\dossier contient maintenant b.txt.

Rayon
la source
8
pour que vous le sachiez, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile appelle File.Move. Les autres remercient de normaliser le fichier d'origine et de faire des vérifications d'erreur supplémentaires sur les arguments, par exemple. le fichier existe, le nom du fichier n'est pas nul, etc. il appelle ensuite File.Move.
Chris Taylor
À moins que Copy () ne copie tous les flux de fichiers, ce qui, je suppose, ne fonctionne pas, je resterais à l'écart de l'utilisation de la suppression / copie. Je suppose que Move (), au moins en restant sur le même système de fichiers, est simplement un renommage et donc tous les flux de fichiers seront conservés.
nickdu
"il échoue sur le réseau" alors vous allez copier et supprimer ce qui est en fait télécharger et télécharger, juste pour la commodité du temps de code ... Quel type de réseau? Dossier partagé Windows ( smb), ftp, sshou quoi que tous ont des commandes / primitives pour le déplacement de fichiers / renommer moins non autorisé (par exemple en lecture seule).
Meow Cat 2012
16

Vous pouvez le copier en tant que nouveau fichier puis supprimer l'ancien en utilisant la System.IO.Fileclasse:

if (File.Exists(oldName))
{
    File.Copy(oldName, newName, true);
    File.Delete(oldName);
}
Zaki Choudhury
la source
4
Note à tous ceux qui lisent ceci: il s'agit d'un anti-modèle, le fichier peut être supprimé ou renommé par un autre processus ou le système d'exploitation entre la vérification de son existence et votre appel à la copie. Vous devez plutôt utiliser une prise d'essai.
user9993
Si le volume est le même, c'est aussi un énorme gaspillage d'E / S car un déplacement ferait en fait un changement de nom au niveau des informations de répertoire.
Adrian Hum
Je traite des milliers de fichiers et j'ai l'impression que Copier / Supprimer est plus rapide que Déplacer.
Roberto
Comment pourrait-on trouver une telle idée. Plus vite ou pas du moins, vous assassinez le disque. En disant "renommer" dans la question, cela devrait signifier renommer localement, ce qui n'implique bien sûr aucun déplacement entre les partitions.
Meow Cat 2012
avec File.Move, j'ai rencontré UnauthorizedAccessException, mais cette séquence de copie et de suppression a fonctionné. Merci!
Oliver Konig
6

REMARQUE: dans cet exemple de code, nous ouvrons un répertoire et recherchons des fichiers PDF avec des parenthèses ouvertes et fermées dans le nom du fichier. Vous pouvez vérifier et remplacer n'importe quel caractère dans le nom que vous aimez ou simplement spécifier un tout nouveau nom en utilisant les fonctions de remplacement.

Il existe d'autres façons de travailler à partir de ce code pour effectuer des renommages plus élaborés, mais mon intention principale était de montrer comment utiliser File.Move pour effectuer un renommage par lots. Cela a fonctionné contre 335 fichiers PDF dans 180 répertoires lorsque je l'ai exécuté sur mon ordinateur portable. C'est le code du moment et il existe des moyens plus élaborés de le faire.

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();
        }
    }
}
MicRoc
la source
3
C'est ... complètement à côté du point, sur une question qui a répondu exactement au point il y a 3 ans.
Nyerguds
2
C'est un exemple valable. Overkill peut-être mais pas à côté du point. +1
Adam
1
@Adam: c'est une implémentation très spécifique de la réponse déjà donnée trois ans auparavant, sur une question qui ne concernait pas une implémentation spécifique en premier lieu. Je ne vois pas en quoi cela est constructif.
Nyerguds
@Nyerguds nous avons alors différentes définitions de «à côté du point», ce qui n'est pas surprenant car c'est un terme subjectif.
Adam
@Nyerguds si cela ne vous concerne pas, c'est bien. Certaines personnes aiment la verbosité car elle les aide à trouver des implémentations "réelles" de code "exemple / exemple". Il renomme les fichiers. Comment c'est à côté du point est à peu près comme Adam l'a dit, c'est subjectif. Pour une raison quelconque, vous pensez que c'est absolument objectif. Eh bien, chacun à lui. Merci pour la contribution, de toute façon.
MicRoc
6

Heureusement! cela vous sera 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);
        }
    }

Comment utiliser ce code?

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

la source
6

Utilisation:

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);
Avinash Singh
la source
5
Si vous allez faire cela, je vous suggère de vérifier que le «oldFilePath» existe avant de faire quoi que ce soit ... sinon vous supprimerez le «newFilePath» sans raison.
John Kroetch
Est-ce que cela compile même ( Using System.IO;)?
Peter Mortensen
3

Dans mon cas, je veux que le nom du fichier renommé soit unique, alors j'ajoute un horodatage au nom. De cette façon, le nom de fichier de l'ancien journal est toujours unique:

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"))));
    }
}
real_yggdrasil
la source
2

Déplacer fait de même = copier et supprimer l'ancien.

File.Move(@"C:\ScanPDF\Test.pdf", @"C:\BackupPDF\" + string.Format("backup-{0:yyyy-MM-dd_HH:mm:ss}.pdf",DateTime.Now));
Nalan Madheswaran
la source
1
Certes, si tout ce qui vous intéresse est le résultat final. En interne, pas tellement.
Michael
Non, Move ne copie et ne supprime certainement pas.
Jim Balter
1

Je n'ai pas trouvé d'approche qui me convient, je propose donc ma version. Bien sûr, vous avez besoin d'entrée, de gestion des erreurs.

public void Rename(string filePath, string newFileName)
{
    var newFilePath = Path.Combine(Path.GetDirectoryName(filePath), newFileName + Path.GetExtension(filePath));
    System.IO.File.Move(filePath, newFilePath);
}
valentasme
la source
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);               
        }
    }
AminGolmahalle
la source
0

J'ai rencontré un cas où j'ai dû renommer le fichier à l'intérieur du gestionnaire d'événements, ce qui déclenchait toute modification de fichier, y compris le renommage, et pour ignorer le renommage indéfini du fichier, je devais le renommer, avec:

  1. Faire sa copie
  2. Retrait de l'original
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

Au cas où quelqu'un aurait un tel scénario;)

Arsen Khachaturyan
la source
0
int rename(const char * oldname, const char * newname);

La fonction rename () est définie dans le fichier d'en-tête stdio.h. Il renomme un fichier ou un répertoire de oldname en newname. L'opération de renommage est identique à déplacer, vous pouvez donc également utiliser cette fonction pour déplacer un fichier.

Meruemu
la source
Bienvenue. Cette question concerne le changement de nom d'un fichier à l'aide du langage C #. Je ne sais pas comment le fait de souligner quelque chose de la bibliothèque standard de C (pas C #) aide ici.
Jeff Dammeyer
-10

Lorsque C # n'a pas de fonctionnalité, j'utilise C ++ ou 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);
    }
}
Alexander Chernosvitov
la source
20
C # a absolument la possibilité de renommer des fichiers.
Andrew Barber
76
Je suis sans voix
Chris McGrath
Merci, c'est exactement ce que je voulais. Il peut changer le nom de soi sur un fichier exécutable.
Jake