Renomeie um arquivo em c #

633

Como renomear um arquivo usando c #?

Ouro
fonte
Detestaria acrescentar que há um problema aqui, todas as soluções aqui, especialmente se você comparar e mover o arquivo de um local para outro (diretório e nome do arquivo), desde que você esteja ciente de que um volume pode ser um ponto de junção ... portanto, se newname for q: \ SomeJunctionDirectory \ hello.txt e o nome antigo for c: \ TargetOfJunctionPoint \ hello.txt ... os arquivos serão os mesmos, mas os nomes não serão.
Adrian Hum

Respostas:

967

Dê uma olhada no System.IO.File.Move , "mova" o arquivo para um novo nome.

System.IO.File.Move("oldfilename", "newfilename");
Chris Taylor
fonte
12
Esta solução não funciona quando os nomes dos arquivos diferem apenas em letras maiúsculas. Por exemplo file.txt e File.txt
SepehrM
2
@ SepehrM, verifiquei duas vezes e funciona bem na minha máquina Windows 8.1.
Chris Taylor
1
@ SepehrM, eu não testei, mas os exemplos que você aponta para usar o FileInfo.Move e não o File.Move, então talvez isso tenha algo a ver com isso?
Chris Taylor
2
Os nomes de sistema de arquivos @SepehrM do Windows não diferenciam maiúsculas de minúsculas. File.txt e file.txt são tratados com o mesmo nome de arquivo. Portanto, não está claro para mim quando você diz que a solução não funciona. O que você está fazendo exatamente que não está funcionando?
Michael
4
@ Michael, o sistema de arquivos não diferencia maiúsculas de minúsculas, mas armazena o nome do arquivo no caso original, conforme digitado pelo usuário. No caso de SepehrM, ele estava tentando alterar o caso de um arquivo, que por algum motivo não estava funcionando. A correspondência sem distinção entre maiúsculas e minúsculas estava funcionando. HTH
Chris Taylor
131
System.IO.File.Move(oldNameFullPath, newNameFullPath);
Aleksandar Vucetic
fonte
47

No método File.Move, isso não substituirá o arquivo se ele já existir. E isso lançará uma exceção.

Portanto, precisamos verificar se o arquivo existe ou não.

/* 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 envolva-o com uma tentativa de tentar evitar uma exceção.

Mohamed Alikhan
fonte
20
tenha muito cuidado com essa abordagem ... se o diretório de destino e o diretório de origem forem iguais, e o "newname" for uma versão que diferencia maiúsculas de minúsculas de "oldFileName", você será excluído antes de ter a chance de mover o arquivo.
Adrian Hum
1
Você também não pode apenas verificar a igualdade das strings, pois existem várias maneiras de representar um único caminho de arquivo.
Drew Noakes
O File.Move agora possui um método de sobrecarga que permite sobrescrever o arquivo - File.Move (oldPath, newPath, true)
Ella
39

Você pode usar File.Movepara fazer isso.

Franci Penov
fonte
34

Basta adicionar:

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

E depois...

FileInfo file = new FileInfo("c:\test.txt");
file.Rename("test2.txt");
Nogro
fonte
... "\\" + newName + fileInfo.Extension
mac10688 15/02
31
eww ... Use Path.Combine () em vez de montar o arquivo.
Adrian Hum
20
  1. Primeira solução

    Evite as System.IO.File.Movesoluções postadas aqui (resposta marcada incluída). Ele falha nas redes. No entanto, o padrão de copiar / excluir funciona localmente e por redes. Siga uma das soluções de movimentação, mas substitua-a por Copiar. Em seguida, use File.Delete para excluir o arquivo original.

    Você pode criar um método Renomear para simplificá-lo.

  2. Fácil de usar

    Use o assembly VB em C #. Adicionar referência ao Microsoft.VisualBasic

    Em seguida, para renomear o arquivo:

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

    Ambos são cordas. Observe que o meu arquivo tem o caminho completo. newName não. Por exemplo:

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

    A C:\whatever\pasta agora conterá b.txt.

Raio
fonte
8
só para você saber, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile chama File.Move. Outro obrigado normalizar o arquivo original e fazer algumas verificações de erro adicionais nos argumentos, por exemplo. existe, o nome do arquivo não é nulo etc., em seguida, chama File.Move.
Chris Taylor
A menos que Copy () copie todos os fluxos de arquivos, o que eu assumo que não, eu ficaria longe de usar excluir / copiar. Suponho que Move (), pelo menos quando permanecer no mesmo sistema de arquivos, é simplesmente uma renomeação e, portanto, todos os fluxos de arquivos serão mantidos.
nickdu
"falha na rede", você copiará e excluirá o que é realmente o download e o upload, apenas por conveniência em tempo de código ... Que tipo de rede? Pasta compartilhada do Windows ( smb), ftp, sshou o que tudo tem comandos / primitivas para mover arquivos / renomear a menos que não é permitido (por exemplo, somente leitura).
Cat Meow 2012
16

Você pode copiá-lo como um novo arquivo e excluir o antigo usando a System.IO.Fileclasse:

if (File.Exists(oldName))
{
    File.Copy(oldName, newName, true);
    File.Delete(oldName);
}
Zaki Choudhury
fonte
4
Nota para quem lê isso: Este é um antipadrão, o arquivo pode ser excluído ou renomeado por outro processo ou sistema operacional entre a verificação da existência e a sua chamada para cópia. Você precisa usar uma tentativa de captura.
user9993
Se o volume for o mesmo, isso também é um enorme desperdício de E / S, pois uma mudança realmente renomeia no nível de informações do diretório.
Adrian Hum
Estou processando milhares de arquivos e tive a impressão de que Copiar / Excluir é mais rápido que o Move.
Roberto Roberto
Como alguém teria essa ideia. Mais rápido ou pelo menos você está matando o disco. Ao dizer "renomear" na pergunta, isso significa renomear localmente, o que obviamente não envolve movimentação entre partições.
Cat Meow 2012
com File.Move, encontrei UnauthorizedAccessException, mas essa sequência de Copiar e Excluir funcionou. Obrigado!
Oliver Konig
6

NOTA: Neste exemplo de código, abrimos um diretório e procuramos arquivos PDF com parênteses abertos e fechados no nome do arquivo. Você pode verificar e substituir qualquer caractere no nome que desejar ou apenas especificar um novo nome usando as funções de substituição.

Existem outras maneiras de trabalhar com esse código para renomear mais elaboradamente, mas minha intenção principal era mostrar como usar o File.Move para renomear em lote. Isso funcionou com 335 arquivos PDF em 180 diretórios quando eu o executei no meu laptop. Este é o código do momento e existem maneiras mais elaboradas de fazê-lo.

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
fonte
3
Isso é ... completamente fora do ponto, em uma pergunta respondida exatamente ao ponto há 3 anos.
perfil completo de Nyerguds
2
É um exemplo válido. Excesso talvez, mas não fora de questão. +1
Adam
1
@ Adam: é uma implementação muito específica, exatamente da resposta que já foi dada três anos antes, em uma pergunta que não tratava de nenhuma implementação específica em primeiro lugar. Não veja como isso é construtivo.
Nyerguds
@ Nyerguds, então temos definições diferentes de 'irrelevante', o que não é surpreendente, pois é um termo subjetivo.
Adam
@ Nyerguds, se é irrelevante para você, então tudo bem. Algumas pessoas gostam de verbosidade porque as ajuda a encontrar implementações do "mundo real" do código "exemplo / exemplo". Renomeia o (s) arquivo (s). Como isso não vem ao caso, é quase como Adam disse, é subjetivo. Por alguma razão, você sente que é absolutamente objetivo. Oh bem, cada um na sua. Obrigado pela entrada, de qualquer maneira.
MicRoc 12/02
6

Esperançosamente! será útil para você. :)

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

Como usar esse 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);
        }
    }

fonte
6

Usar:

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
fonte
5
Se você fizer isso, sugiro verificar se o 'oldFilePath' existe antes de fazer qualquer coisa ... ou então você excluirá o 'newFilePath' sem motivo.
John Kroetch
Isso compila ( Using System.IO;)?
Peter Mortensen
3

No meu caso, quero que o nome do arquivo renomeado seja exclusivo, portanto, adiciono um carimbo de data e hora ao nome. Dessa forma, o nome do arquivo do log 'antigo' é sempre exclusivo:

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

O Move está fazendo o mesmo = Copie e exclua o antigo.

File.Move(@"C:\ScanPDF\Test.pdf", @"C:\BackupPDF\" + string.Format("backup-{0:yyyy-MM-dd_HH:mm:ss}.pdf",DateTime.Now));
Nalan Madheswaran
fonte
1
Verdade, se tudo o que importa é o resultado final. Internamente, nem tanto.
Michael
Não, o Move certamente não copia e exclui.
Jim Balter
1

Não consegui encontrar uma abordagem que combina comigo, então proponho minha versão. Claro que precisa de entrada, tratamento de erros.

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
fonte
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
fonte
0

Encontrei um caso em que tive que renomear o arquivo dentro do manipulador de eventos, que estava sendo acionado para qualquer alteração no arquivo, incluindo renomear, e para pular a renomeação permanente do arquivo, tive que renomeá-lo, com:

  1. Fazendo sua cópia
  2. Removendo o 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);

Apenas no caso, se alguém, terá esse cenário;)

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

A função rename () é definida no arquivo de cabeçalho stdio.h. Renomeia um arquivo ou diretório de oldname para newname. A operação de renomeação é a mesma que mover, portanto, você também pode usar esta função para mover um arquivo.

Meruemu
fonte
Bem-vinda. Esta pergunta é sobre como renomear um arquivo usando a linguagem C #. Não sei como apontar algo da biblioteca padrão de C (não C #) ajuda aqui.
Jeff Dammeyer
-10

Quando o C # não tem algum recurso, eu uso 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
fonte
20
C # absolutamente tem a capacidade de renomear arquivos.
Andrew Barber
76
Estou sem palavras
Chris McGrath
Obrigado, é exatamente isso que eu queria. Pode alterar o nome próprio em um arquivo executável.
21418 Jake