Cambiar el nombre de un archivo en C #

633

¿Cómo cambio el nombre de un archivo con C #?

Oro
fuente
Odiaría agregar que aquí hay un problema con todas las soluciones, especialmente si compara y está moviendo el archivo de una ubicación a otra (directorio y nombre de archivo) en la medida en que debe saber que un volumen podría ser un punto de unión ... así que si newname es q: \ SomeJunctionDirectory \ hello.txt y el nombre anterior es c: \ TargetOfJunctionPoint \ hello.txt ... los archivos son los mismos pero los nombres no.
Adrian Hum

Respuestas:

967

Eche un vistazo a System.IO.File.Move , "mueva" el archivo a un nuevo nombre.

System.IO.File.Move("oldfilename", "newfilename");
Chris Taylor
fuente
12
Esta solución no funciona cuando los nombres de los archivos difieren solo en mayúsculas y minúsculas. Por ejemplo file.txt y File.txt
SepehrM
2
@SepehrM, acabo de verificar y funciona bien en mi máquina con Windows 8.1.
Chris Taylor
1
@SepehrM, no lo probé, pero las muestras que señalas para usar FileInfo.Move y no File.Move, ¿tal vez eso tenga algo que ver con eso?
Chris Taylor
2
@SepehrM Los nombres de sistema de archivos de Windows no distinguen entre mayúsculas y minúsculas. File.txt y file.txt se tratan como el mismo nombre de archivo. Entonces no me queda claro cuando dices que la solución no funciona. ¿Qué haces exactamente que no funciona?
Michael
44
@Michael, el sistema de archivos no distingue entre mayúsculas y minúsculas, pero almacena el nombre de archivo en el caso original tal como lo ingresó el usuario. En el caso de SepehrM, estaba tratando de cambiar el caso de un archivo, que por alguna razón no estaba funcionando. La coincidencia entre mayúsculas y minúsculas estaba funcionando. HTH
Chris Taylor
131
System.IO.File.Move(oldNameFullPath, newNameFullPath);
Aleksandar Vucetic
fuente
47

En el método File.Move, esto no sobrescribirá el archivo si ya existe. Y arrojará una excepción.

Por lo tanto, debemos verificar si el archivo existe 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 rodearlo con un intento de captura para evitar una excepción.

Mohamed Alikhan
fuente
21
tenga mucho cuidado con este enfoque ... si su directorio de destino y su directorio de origen son los mismos, y el "nombre nuevo" en realidad es una versión que distingue entre mayúsculas y minúsculas de "oldFileName", eliminará antes de tener la oportunidad de mover su archivo.
Adrian Hum
1
Tampoco puede simplemente verificar la igualdad de las cadenas, ya que hay varias formas de representar una única ruta de archivo.
Drew Noakes
File.Move tiene un método de sobrecarga ahora que le permite sobrescribir el archivo - File.Move (oldPath, newPath, true)
Ella
34

Solo agrega:

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

Y entonces...

FileInfo file = new FileInfo("c:\test.txt");
file.Rename("test2.txt");
Nogro
fuente
... "\\" + newName + fileInfo.Extension
mac10688
31
eww ... Use Path.Combine () en lugar de ensamblar el archivo.
Adrian Hum
20
  1. Primera solución

    Evite las System.IO.File.Movesoluciones publicadas aquí (respuesta marcada incluida). Falla en las redes. Sin embargo, el patrón copiar / eliminar funciona localmente y a través de redes. Siga una de las soluciones de movimiento, pero reemplácela con Copiar. Luego use File.Delete para eliminar el archivo original.

    Puede crear un método de cambio de nombre para simplificarlo.

  2. Facilidad de uso

    Use el ensamblaje VB en C #. Agregar referencia a Microsoft.VisualBasic

    Luego, para cambiar el nombre del archivo:

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

    Ambas son cuerdas. Tenga en cuenta que myfile tiene la ruta completa. newName no lo hace. Por ejemplo:

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

    La C:\whatever\carpeta ahora contendrá b.txt.

Rayo
fuente
8
para que lo sepas, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile llama a File.Move. Otros agradecen la normalización del archivo original y hacen algunas verificaciones de error adicionales en los argumentos, es decir. el archivo existe, el nombre del archivo no es nulo, etc., luego llama a File.Move.
Chris Taylor
A menos que Copiar () copie todas las secuencias de archivos, lo que supongo que no lo hace, me mantendría alejado de usar borrar / copiar. Supongo que Move (), al menos cuando permanece en el mismo sistema de archivos, es simplemente un cambio de nombre y, por lo tanto, se mantendrán todas las secuencias de archivos.
nickdu
"falla en la red", entonces va a copiar y eliminar lo que en realidad es descargar y cargar, solo por conveniencia de tiempo de código ... ¿Qué tipo de red? Carpeta compartida de Windows ( smb), ftp, ssho lo que todos tienen comandos / primitivas para el archivo de movimiento / cambio de nombre a menos que no lo permita (por ejemplo, de sólo lectura).
Meow Cat 2012
16

Puede copiarlo como un archivo nuevo y luego eliminar el anterior usando la System.IO.Fileclase:

if (File.Exists(oldName))
{
    File.Copy(oldName, newName, true);
    File.Delete(oldName);
}
Zaki Choudhury
fuente
44
Nota para cualquiera que lea esto: este es un antipatrón, el archivo puede ser eliminado o renombrado por otro proceso o el sistema operativo entre la verificación de si existe y su llamada a Copiar. En su lugar, debe usar un try catch.
user9993
Si el volumen es el mismo, esto también es un gran desperdicio de E / S ya que un movimiento realmente cambiaría el nombre a nivel de información del directorio.
Adrian Hum
Estoy procesando miles de archivos y tengo la impresión de que Copiar / Eliminar es más rápido que Mover.
Roberto
¿Cómo se le ocurriría a alguien una idea así? Más rápido o no al menos estás asesinando el disco. Al decir "cambiar nombre" en la pregunta, debería significar cambiar el nombre localmente, lo que por supuesto no implica ningún movimiento de partición cruzada.
Meow Cat 2012
con File.Move me encontré con UnauthorizedAccessException, pero esta secuencia de Copiar y Eliminar funcionó. ¡Gracias!
Oliver Konig
6

NOTA: En este código de ejemplo, abrimos un directorio y buscamos archivos PDF con paréntesis abiertos y cerrados en el nombre del archivo. Puede verificar y reemplazar cualquier carácter en el nombre que desee o simplemente especificar un nombre completamente nuevo usando las funciones de reemplazo.

Hay otras formas de trabajar desde este código para hacer cambios de nombre más elaborados, pero mi intención principal era mostrar cómo usar File.Move para hacer un cambio de nombre por lotes. Esto funcionó contra 335 archivos PDF en 180 directorios cuando lo ejecuté en mi computadora portátil. Este es el código del momento y hay formas más elaboradas de hacerlo.

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
fuente
3
Eso es ... completamente al margen del punto, en una pregunta respondida exactamente al punto hace 3 años.
Nyerguds
2
Es un ejemplo válido. Tal vez exagerar pero no fuera del punto. +1
Adam
1
@ Adam: es una implementación muy específica de exactamente la respuesta que ya se dio tres años antes, en una pregunta que no se refería a ninguna implementación específica en primer lugar. No veo cómo eso es constructivo.
Nyerguds
@Nyerguds, entonces tenemos diferentes definiciones de 'aparte del punto', lo cual no es sorprendente ya que es un término subjetivo.
Adam
@Nyerguds si es irrelevante para ti, entonces está bien. A algunas personas les gusta la verbosidad porque les ayuda a encontrar implementaciones "reales" del código "muestra / ejemplo". Cambia el nombre de los archivos. La forma en que está fuera del punto es más o menos como Adam dijo, es subjetiva. Por alguna razón, sientes que es absolutamente objetivo. Oh, bueno, a cada uno lo suyo. Gracias por el aporte, de cualquier manera.
MicRoc
6

¡Ojalá! Será útil para usted. :)

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

¿Cómo usar este código?

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

fuente
6

Utilizar:

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
fuente
55
Si va a hacer esto, le sugiero que compruebe que el 'oldFilePath' existe antes de hacer algo ... o de lo contrario eliminará el 'newFilePath' sin ningún motivo.
John Kroetch
¿Eso incluso compila ( Using System.IO;)?
Peter Mortensen
3

En mi caso, quiero que el nombre del archivo renombrado sea único, así que agrego una marca de fecha y hora al nombre. De esta manera, el nombre de archivo del registro 'antiguo' siempre es único:

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
fuente
2

Move está haciendo lo mismo = Copiar y eliminar el anterior.

File.Move(@"C:\ScanPDF\Test.pdf", @"C:\BackupPDF\" + string.Format("backup-{0:yyyy-MM-dd_HH:mm:ss}.pdf",DateTime.Now));
Nalan Madheswaran
fuente
1
Es cierto, si todo lo que le importa es el resultado final. Internamente, no tanto.
Michael
No, Mover ciertamente no copia ni elimina.
Jim Balter
1

No pude encontrar un enfoque que me convenga, así que propongo mi versión. Por supuesto necesita entrada, manejo de errores.

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

Encontré un caso en el que tuve que cambiar el nombre del archivo dentro del controlador de eventos, lo que provocó cualquier cambio de archivo, incluido el cambio de nombre, y para omitir el cambio de nombre del archivo, tuve que cambiar el nombre, con:

  1. Haciendo su copia
  2. Retirar el 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);

Por si acaso si alguien, tendrá ese escenario;)

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

La función rename () se define en el archivo de encabezado stdio.h. Cambia el nombre de un archivo o directorio de oldname a newname. La operación de cambio de nombre es la misma que mover, por lo tanto, también puede usar esta función para mover un archivo.

Meruemu
fuente
Bienvenidos. Esta pregunta se trata de renombrar un archivo usando el lenguaje C #. No estoy seguro de cómo señalar algo de la biblioteca estándar de C (no C #) ayuda aquí.
Jeff Dammeyer
-10

Cuando C # no tiene alguna característica, uso 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);
    }
}
Alexander Chernosvitov
fuente
20
C # tiene la capacidad de cambiar el nombre de los archivos.
Andrew Barber
76
Estoy sin palabras
Chris McGrath
Gracias, esto es exactamente lo que quería. Puede cambiar el nombre propio en un archivo ejecutable.
Jake