C # 'da bir dosyayı yeniden adlandırma


632

C # kullanarak bir dosyayı nasıl yeniden adlandırabilirim?


Burada bir sorun olduğunu eklemekten nefret ediyorum özellikle burada karşılaştırır ve dosyayı bir birimden diğerine (dizin yanı sıra dosya adı) taşıyorsanız, bir birim olabileceğini bilmeniz gerekir. birleşim noktası ... eğer yeni ad q: \ SomeJunctionDirectory \ hello.txt ise ve eski ad c: \ TargetOfJunctionPoint \ hello.txt ise ... dosyalar aynı ancak isimler aynı değildir.
Adrian Hum

Yanıtlar:


966

System.IO.File.Move dosyasına bir bakın , dosyayı yeni bir isme "taşıyın".

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

12
Dosya adları yalnızca harf büyüklüğünde farklılık gösterdiğinde bu çözüm çalışmaz. Örneğin file.txt ve
File.txt

2
@SepehrM, sadece iki kez kontrol ettim ve Windows 8.1 makinemde iyi çalışıyor.
Chris Taylor

1
@SepehrM, ben test etmedim, ama FileInfo.Move kullanmak için işaret ettiğiniz örnekleri ve File.Move değil, bu yüzden belki onunla bir şey var?
Chris Taylor

2
@SepehrM Windows dosya sistemi adları büyük / küçük harfe duyarlı değildir. Dosya.txt ve dosya.txt aynı dosya adı olarak kabul edilir. Bu yüzden çözümün işe yaramadığını söylediğinizde benim için net değil. Tam olarak ne işe yaramıyor?
Michael

4
@Michael, dosya sistemi büyük / küçük harfe duyarsızdır, ancak dosya adını kullanıcı tarafından girildiği şekilde orijinal durumda saklar. SepehrM'in davasında, bir nedenden dolayı çalışmayan bir dosyayı değiştirmeye çalışıyordu. Olguya duyarsız eşleşme çalışıyordu. HTH
Chris Taylor


47

File.Move yönteminde, zaten varsa dosyanın üzerine yazılmaz. Ve bir istisna atacak.

Bu yüzden dosyanın var olup olmadığını kontrol etmeliyiz.

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

Veya bir istisnayı önlemek için bir deneme yakalama ile çevreleyin.


20
bu yaklaşıma gerçekten dikkat edin ... Hedef dizininiz ve kaynak dizininiz aynıysa ve "yeni ad" aslında "oldFileName" in büyük / küçük harf duyarlı bir sürümü ise, dosyanızı taşıma şansı elde etmeden önce silersiniz.
Adrian Hum

1
Tek bir dosya yolunu temsil etmenin birkaç yolu olduğundan, dizeleri eşitlik açısından kontrol edemezsiniz.
Drew Noakes

File.Move, dosyanın üzerine yazmanıza izin veren bir aşırı yükleme yöntemine sahiptir - File.Move (oldPath, newPath, true)
Ella


34

Sadece ekle:

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

Ve sonra...

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

... "\\" + newName + fileInfo.Extension
mac10688 15:16

31
eww ... Dosyayı birleştirmek yerine Path.Combine () kullanın.
Adrian Hum

20
  1. İlk çözüm

    System.IO.File.MoveBurada gönderilen çözümlerden kaçının (işaretli cevap dahil). Ağlar üzerinden başarısız olur. Ancak, desen kopyalama / silme yerel olarak ve ağlar üzerinde çalışır. Taşıma çözümlerinden birini uygulayın, ancak bunun yerine Kopyala ile değiştirin. Ardından File.Delete dosyasını kullanarak orijinal dosyayı silin.

    Basitleştirmek için bir Yeniden Adlandırma yöntemi oluşturabilirsiniz.

  2. Kullanım kolaylığı

    C # 'da VB montaj kullanın. Microsoft.VisualBasic'e başvuru ekleyin

    Sonra dosyayı yeniden adlandırmak için:

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

    Her ikisi de dizedir. Dosyamın tam yolu olduğunu unutmayın. newName bunu yapmaz. Örneğin:

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

    C:\whatever\Klasör artık içerecektir b.txt.


8
bildiğiniz gibi, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile File.Move'u çağırır. Diğerleri orijinal dosyayı normalleştiriyor ve argümanlar üzerinde bazı ek hata kontrolleri yapıyor. dosya var, dosya adı boş değil vb. sonra File.Move çağırır.
Chris Taylor

Copy () tüm dosya akışlarını kopyalamazsa, öyle olmadığını varsayarsam, delete / copy kullanmaktan uzak dururum. Move (), en azından aynı dosya sisteminde kalırken, sadece bir yeniden adlandırma olduğunu ve bu nedenle tüm dosya akışlarının korunacağını varsayıyorum.
nickdu

"ağ üzerinden başarısız" sonra sadece kod-zaman rahatlığı için, aslında indirme ve yükleme olan kopyalamak & silmek olacak ... Ne tür bir ağ? Pencereler (klasör paylaşılan smb), ftp, sshya da her türlü şeye sahip komutları / ilkel dosya hareketli için / izin verilmez sürece yeniden adlandırma (örneğin salt okunur).
Miyav Kedisi 2012

16

System.IO.FileSınıfı kullanarak yeni bir dosya olarak kopyalayabilir ve eskisini silebilirsiniz :

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

4
Bunu okuyan herkes için not: Bu bir anti-desen, dosya başka bir işlem veya işletim sistemi tarafından var olup olmadığını kontrol etme ve Kopyalama çağrısı arasında silinebilir veya yeniden adlandırılabilir. Bunun yerine bir try catch kullanmanız gerekir.
user9993

Birim aynı ise, bir hareket aslında dizin bilgi düzeyinde yeniden adlandırma yapacağından, bu büyük bir I / O israfıdır.
Adrian Hum

Binlerce dosyayı işliyorum ve Kopyala / Sil hareketinden daha hızlı olduğu izlenimini edindim.
Roberto

Nasıl böyle bir fikir ortaya çıkardı. Daha hızlı veya en azından diski öldürüyorsunuz. Soruda "yeniden adlandır" diyerek, yerel olarak yeniden adlandırmak anlamına gelir ki, elbette hiçbir çapraz bölüm hareketini içermez.
Miyav Kedisi 2012

File.Move ile UnauthorizedAccessException girdim, ancak bu Kopyala ve Sil dizisi çalıştı. Teşekkürler!
Oliver Konig

6

NOT: Bu örnek kodda, bir dizin açarız ve dosya adına açık ve kapalı parantezli PDF dosyalarını ararız. İstediğiniz addaki herhangi bir karakteri kontrol edebilir ve değiştirebilir veya yerine koyma işlevlerini kullanarak tamamen yeni bir ad belirleyebilirsiniz.

Daha ayrıntılı yeniden adlandırmalar yapmak için bu koddan çalışmanın başka yolları da var, ancak asıl amacım toplu yeniden adlandırma yapmak için File.Move'un nasıl kullanılacağını göstermekti. Bu, dizüstü bilgisayarımda çalıştırdığımda 180 dizinde 335 PDF dosyasına karşı çalıştı. Bu moment kodunun teşvikidir ve bunu yapmanın daha ayrıntılı yolları vardır.

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
Bu ... noktanın tamamen yanında, 3 yıl önce tam olarak cevaplanan bir soru üzerine.
Nyerguds

2
Geçerli bir örnek. Aşırıya kaçma belki ama noktanın yanında değil. +1
Adam

1
@Adam: İlk olarak herhangi bir özel uygulama ile ilgili olmayan bir soru üzerine, üç yıl önce verilen cevabın çok spesifik bir uygulaması. Bunun nasıl bir şekilde yapıcı olduğunu görmeyin.
Nyerguds

@ Nyerguds, öznel bir terim olduğu için şaşırtıcı olmayan 'noktanın yanında' farklı tanımlarımız var.
Adam

@ Nyerguds senin için alakasızsa o zaman sorun değil. Bazı insanlar ayrıntılardan hoşlanırlar çünkü "örnek / örnek" kodunun "gerçek dünya" uygulamalarını bulmalarına yardımcı olur. Dosya (lar) ı yeniden adlandırır. Konunun yanı sıra Adem'in söylediği gibi, bu özneldir. Nedense kesinlikle nesnel olduğunu hissediyorsunuz. Oh, her biri kendi için. Her iki şekilde de girdi için teşekkürler.
MicRoc

6

İnşallah! sizin için yararlı olacaktır. :)

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

Bu kod nasıl kullanılır?

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

kullanın:

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
Bunu yapacaksanız, herhangi bir şey yapmadan önce 'oldFilePath' öğesinin var olup olmadığını kontrol etmenizi öneririm ... yoksa başka bir nedenle 'newFilePath' i silersiniz.
John Kroetch

Bu bile derleniyor ( Using System.IO;)?
Peter Mortensen

3

Benim durumumda, yeniden adlandırılan dosyanın adının benzersiz olmasını istiyorum, bu nedenle ada bir tarih-saat damgası ekliyorum. Bu şekilde, 'eski' günlüğün dosya adı her zaman benzersizdir:

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

Move aynı şeyi yapıyor = Eskisini Kopyala ve Sil.

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

1
Doğru, umursadığınız tek şey sonuçsa. Dahili olarak, çok fazla değil.
Michael

Hayır, Taşı kesinlikle Kopyalama ve Silme işlemlerini yapmaz.
Jim Balter

1

Bana uygun bir yaklaşım bulamadım, bu yüzden versiyonumu öneriyorum. Tabii ki girdi, hata işleme gerekir.

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

Ben olay yeniden adlandırıcı da dahil olmak üzere herhangi bir dosya değişikliği için tetikleyen ve dosyayı yeniden adlandırmak sonsuza dek atlamak için, olay işleyicisi içinde dosyayı yeniden adlandırmak zorunda kaldım bir durumla karşılaştım:

  1. Kopyasını çıkarmak
  2. Orijinali çıkarma
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

Birisinin böyle bir senaryoya sahip olması durumunda;)


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

rename () işlevi stdio.h başlık dosyasında tanımlanır. Bir dosya veya dizini eski addan yeni ada yeniden adlandırır. Yeniden adlandırma işlemi taşıma ile aynıdır, bu nedenle bir dosyayı taşımak için de bu işlevi kullanabilirsiniz.


Hoşgeldiniz. Bu soru, bir dosyayı C # dilini kullanarak yeniden adlandırmayla ilgilidir. C (değil C #) standart kitaplığından bir şey işaret nasıl yardımcı emin değilim.
Jeff Dammeyer

-10

C # bazı özelliği olmadığında, C ++ veya C kullanın:

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 # kesinlikle dosyaları yeniden adlandırma yeteneğine sahiptir.
Andrew Barber

76
Ben suskunum
Chris McGrath

Teşekkürler, Bu tam olarak istediğim şeydi. Yürütülebilir bir dosyada kendi adını değiştirebilir.
Jake
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.