Zmień nazwę pliku w C #


632

Jak zmienić nazwę pliku przy użyciu C #?


Nie chciałbym dodawać, że tutaj jest problem, wszystkie rozwiązania tutaj, szczególnie jeśli porównujesz i przenosisz plik z jednej lokalizacji do innej (katalog oraz nazwa pliku), o ile powinieneś wiedzieć, że wolumin może być punkt połączenia ... więc jeśli nowa nazwa to q: \ SomeJunctionDirectory \ hello.txt, a stara nazwa to c: \ TargetOfJunctionPoint \ hello.txt ... pliki są takie same, ale nazwy nie są.
Adrian Hum

Odpowiedzi:


966

Spójrz na System.IO.File.Move , „przenieś” plik do nowej nazwy.

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

12
To rozwiązanie nie działa, gdy nazwy plików różnią się tylko wielkością liter. Na przykład file.txt i File.txt
SepehrM

2
@ SepehrM, właśnie dwukrotnie sprawdziłem i działa dobrze na moim komputerze z systemem Windows 8.1.
Chris Taylor

1
@ SepehrM, nie testowałem tego, ale próbki, które wskazałeś, używają FileInfo.Move, a nie File.Move, więc może to ma coś z tym wspólnego?
Chris Taylor

2
@SepehrM Nazwy systemów plików Windows nie rozróżniają wielkości liter. File.txt i file.txt są traktowane jako ta sama nazwa pliku. Więc nie jest dla mnie jasne, kiedy mówisz, że rozwiązanie nie działa. Co robisz dokładnie to nie działa?
Michael

4
@Michael, w systemie plików nie jest rozróżniana wielkość liter, ale przechowuje nazwę pliku w oryginalnej wielkości wpisanej przez użytkownika. W przypadku SepehrM próbował zmienić przypadek pliku, który z jakiegoś powodu nie działał. Działa dopasowanie bez rozróżniania wielkości liter. HTH
Chris Taylor


47

W metodzie File.Move nie zastąpi to pliku, jeśli już istnieje. I to rzuci wyjątek.

Musimy więc sprawdzić, czy plik istnieje, czy nie.

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

Możesz też otoczyć go próbującym haczykiem, aby uniknąć wyjątku.


20
bądźcie bardzo ostrożni z tym podejściem ... jeśli katalog docelowy i katalog źródłowy są takie same, a „nowa nazwa” to tak naprawdę rozróżniana wielkość liter wersja „oldFileName”, usuniecie go, zanim będzie można przenieść plik.
Adrian Hum

1
Nie można również po prostu sprawdzić ciągów pod kątem równości, ponieważ istnieje kilka sposobów reprezentowania pojedynczej ścieżki pliku.
Drew Noakes,

File.Move ma teraz metodę przeciążenia, która pozwala na zastąpienie pliku - File.Move (oldPath, newPath, true)
Ella


34

Poprostu dodaj:

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

I wtedy...

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

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

31
eww ... Użyj Path.Combine () zamiast kompilacji pliku.
Adrian Hum

20
  1. Pierwsze rozwiązanie

    Unikaj System.IO.File.Movezamieszczonych tutaj rozwiązań (w tym zaznaczona odpowiedź). Awarie w sieciach. Jednak wzór kopiowania / usuwania działa lokalnie i przez sieci. Postępuj zgodnie z jednym z rozwiązań przenoszenia, ale zamiast tego zastąp go Kopiuj. Następnie użyj File.Delete, aby usunąć oryginalny plik.

    Możesz utworzyć metodę zmiany nazwy, aby ją uprościć.

  2. Łatwość użycia

    Użyj zestawu VB w C #. Dodaj odwołanie do Microsoft.VisualBasic

    Następnie, aby zmienić nazwę pliku:

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

    Oba są strunami. Zauważ, że mój plik ma pełną ścieżkę. newName nie. Na przykład:

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

    C:\whatever\Folder będzie teraz zawierać b.txt.


8
po prostu wiesz, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile wywołuje File.Move. Inne podziękowania za normalizację oryginalnego pliku i wykonanie dodatkowych kontroli błędów argumentów, tj. plik istnieje, nazwa pliku nie jest pusta itp. Następnie wywołuje File.Move.
Chris Taylor

O ile Copy () nie skopiuje wszystkich strumieni plików, co, jak zakładam, nie robi, nie będę używać usuwania / kopiowania. Zakładam, że Move (), przynajmniej podczas pozostawania w tym samym systemie plików, to po prostu zmiana nazwy i dlatego wszystkie strumienie plików zostaną zachowane.
nickdu

„nie działa w sieci”, a następnie skopiujesz i usuniesz to, co faktycznie jest pobierane i przesyłane, tylko dla wygody kodowania ... Jakiej sieci? Udostępniony folder Windows ( smb) ftp, sshlub cokolwiek wszyscy mają komendy / prymitywy dla plików Przenoszenie / zmiana nazwy, chyba że nie jest dozwolone (np tylko do odczytu).
Meow Cat 2012

16

Możesz skopiować go jako nowy plik, a następnie usunąć stary, używając System.IO.Fileklasy:

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

4
Uwaga dla każdego, kto to czyta: To jest anty-wzorzec, plik może zostać usunięty lub przemianowany przez inny proces lub system operacyjny między sprawdzaniem, czy istnieje a twoim wezwaniem do kopiowania. Zamiast tego musisz użyć try catch.
user9993 20.04.2016

Jeśli wolumin jest taki sam, oznacza to również ogromną stratę we / wy, ponieważ przeniesienie faktycznie spowodowałoby zmianę nazwy na poziomie informacji o katalogu.
Adrian Hum,

Przetwarzam tysiące plików i mam wrażenie, że Kopiuj / Usuń jest szybszy niż Przenieś.
Roberto,

Jak ktokolwiek wpadłby na taki pomysł. Szybciej, a przynajmniej nie, mordujesz dysk. Mówiąc „zmień nazwę” w pytaniu, powinno to oznaczać zmianę nazwy lokalnej, co oczywiście nie wymaga przenoszenia między partycjami.
Meow Cat 2012

z File.Move natknąłem się na UnauthorizedAccessException, ale ta sekwencja Kopiuj i Usuń działała. Dzięki!
Oliver Konig,

6

UWAGA: W tym przykładowym kodzie otwieramy katalog i szukamy plików PDF z otwartym i zamkniętym nawiasiem w nazwie pliku. Możesz sprawdzić i zamienić dowolny znak w nazwie, którą lubisz lub po prostu podać całą nową nazwę za pomocą funkcji zamiany.

Istnieją inne sposoby pracy z tym kodem, aby dokonywać bardziej skomplikowanych zmian nazw, ale moim głównym zamiarem było pokazanie, jak używać File.Move, aby zmienić nazwę partii. Działa to przeciwko 335 plikom PDF w 180 katalogach, kiedy uruchomiłem go na swoim laptopie. To jest kod aktualnej chwili i istnieją bardziej skomplikowane sposoby, aby to zrobić.

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
To ... zupełnie nie na temat, na pytanie, na które dokładnie odpowiedziałem 3 lata temu.
Nyerguds,

2
To ważny przykład. Przesadzenie może, ale nie bez sensu. +1
Adam

1
@Adam: jest to bardzo konkretne wdrożenie dokładnie takiej odpowiedzi, która została już udzielona trzy lata wcześniej, na pytanie, które nie dotyczyło żadnego konkretnego wdrożenia. Nie rozumiem, jak to jest w jakikolwiek sposób konstruktywne.
Nyerguds,

@Nyerguds mamy zatem różne definicje „poza punktem”, co nie jest zaskakujące, ponieważ jest to termin subiektywny.
Adam,

@Nyerguds, jeśli jest to dla ciebie nieistotne, to jest w porządku. Niektórzy ludzie lubią gadatliwość, ponieważ pomaga im znaleźć implementacje kodu „sample / example” w „prawdziwym świecie”. Zmienia nazwy plików. To, co jest poza tym, jest w zasadzie, jak powiedział Adam, subiektywne. Z jakiegoś powodu uważasz, że jest to absolutnie obiektywne. No cóż, każdemu swojemu. Dzięki za wkład, tak czy inaczej.
MicRoc

6

Ufnie! to będzie dla ciebie pomocne. :)

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

Jak korzystać z tego kodu?

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

Posługiwać się:

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
Jeśli masz zamiar to zrobić, sugeruję sprawdzenie, czy „oldFilePath” istnieje przed zrobieniem czegoś ... w przeciwnym razie usuniesz „newFilePath” bez żadnego powodu.
John Kroetch,

Czy to w ogóle kompiluje ( Using System.IO;)?
Peter Mortensen

3

W moim przypadku chcę, aby nazwa pliku o zmienionej nazwie była unikalna, dlatego dodam do niej znacznik daty i godziny. W ten sposób nazwa „starego” dziennika jest zawsze unikalna:

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

Przenieś robi to samo = Skopiuj i usuń stary.

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

1
To prawda, jeśli zależy Ci tylko na wyniku końcowym. Wewnętrznie nie tak bardzo.
Michael,

Nie, Przenieś z pewnością nie kopiuje i nie usuwa.
Jim Balter,

1

Nie mogłem znaleźć podejścia, które mi odpowiada, więc proponuję swoją wersję. Oczywiście potrzebujesz danych wejściowych, obsługi błędów.

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

Zetknąłem się z przypadkiem, gdy musiałem zmienić nazwę pliku w module obsługi zdarzeń, który był wyzwalany dla każdej zmiany pliku, w tym zmiany nazwy, i aby pominąć na zawsze zmianę nazwy pliku, musiałem zmienić jego nazwę za pomocą:

  1. Robienie kopii
  2. Usuwanie oryginału
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

Na wypadek, gdyby ktoś miał taki scenariusz;)


-10

Kiedy C # nie ma żadnej funkcji, używam C ++ lub 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 # absolutnie ma możliwość zmiany nazw plików.
Andrew Barber

76
Zaniemówiłem
Chris McGrath,

Dzięki, właśnie tego chciałem. Może zmienić własną nazwę w pliku wykonywalnym.
Jake,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.