【问题标题】:Rename a file in C#在 C# 中重命名文件
【发布时间】:2011-03-14 05:34:09
【问题描述】:

如何使用 C# 重命名文件?

【问题讨论】:

  • 我不想补充一点,这里的所有解决方案都存在问题,特别是如果您进行比较并将文件从一个位置移动到另一个位置(目录和文件名),只要你应该请注意,一个卷可能是一个连接点......所以如果新名称是 q:\SomeJunctionDirectory\hello.txt 并且旧名称是 c:\TargetOfJunctionPoint\hello.txt......文件是相同的,但名称是't。

标签: c# file rename


【解决方案1】:

看看System.IO.File.Move,将文件“移动”到一个新名称。

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

【讨论】:

  • 当文件名仅在字母大小写上不同时,此解决方案不起作用。例如 file.txt 和 File.txt
  • @SepehrM,我刚刚仔细检查了一下,它在我的 Windows 8.1 机器上运行良好。
  • @SepehrM,我没有测试它,但是您指向的示例使用 FileInfo.Move 而不是 File.Move,所以也许这与它有关?
  • @SepehrM Windows 文件系统名称不区分大小写。 File.txt 和 file.txt 被视为相同的文件名。所以当你说解决方案不起作用时,我不清楚。你到底在做什么不工作?
  • @Michael,文件系统不区分大小写,但它确实以用户输入的原始大小写存储文件名。在 SepehrM 的案例中,他试图更改文件的大小写,但由于某种原因无法正常工作。不区分大小写的匹配正在工作。 HTH
【解决方案2】:
System.IO.File.Move(oldNameFullPath, newNameFullPath);

【讨论】:

    【解决方案3】:

    在 File.Move 方法中,如果文件已存在,则不会覆盖该文件。而且会抛出异常。

    所以我们需要检查文件是否存在。

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

    或者用 try catch 包围它以避免异常。

    【讨论】:

    • 这种方法要非常小心...如果您的目标目录和源目录相同,并且“newname”实际上是“oldFileName”的区分大小写的版本,您将在您之前删除有机会移动您的文件。
    • 您也不能只检查字符串是否相等,因为有多种表示单个文件路径的方法。
    • File.Move 现在有一个重载方法,允许您覆盖文件 - File.Move(oldPath, newPath, true)
    • @Ella 我在 File.Move 中看不到第三个参数。
    • @RobertSF 在 .Net core 3.0 及更高版本中 - docs.microsoft.com/en-us/dotnet/api/…
    【解决方案4】:

    只需添加:

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

    然后……

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

    【讨论】:

    • ... "\\" + newName + fileInfo.Extension
    • eww... 使用 Path.Combine() 而不是组装文件。
    【解决方案5】:

    你可以使用File.Move来做。

    【讨论】:

      【解决方案6】:
      1. 第一个解决方案

        避免在此处发布System.IO.File.Move 解决方案(包括标记的答案)。 它故障转移网络。但是,复制/删除模式在本地和网络上都有效。遵循其中一种移动解决方案,但将其替换为复制。然后使用 File.Delete 删除原始文件。

        您可以创建一个 Rename 方法来简化它。

      2. 易于使用

        在 C# 中使用 VB 程序集。 添加对 Microsoft.VisualBasic 的引用

        然后重命名文件:

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

        两者都是字符串。请注意, myfile 具有完整路径。 newName 没有。 例如:

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

        C:\whatever\ 文件夹现在将包含 b.txt

      【讨论】:

      • 您知道,Microsoft.VisualBasic.FileIO.FileSystem.RenameFile 调用 File.Move。其他感谢规范化原始文件并对参数进行一些额外的错误检查,即。文件存在,文件名不为空等,然后调用 File.Move。
      • 除非 Copy() 复制所有文件流,我认为它不会,否则我会远离使用删除/复制。我假设 Move(),至少当停留在同一个文件系统上时,只是一个重命名,因此所有文件流都将被维护。
      • “它在网络上发生故障”然后你将复制和删除实际上是下载和上传的,只是为了代码时间的方便......什么样的网络? Windows 共享文件夹 (smb)、ftpssh 或任何具有用于文件移动/重命名的命令/原语,除非不允许(例如只读)。
      【解决方案7】:

      您可以将其复制为一个新文件,然后使用 System.IO.File 类删除旧文件:

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

      【讨论】:

      • 阅读此文的任何人请注意:这是一种反模式,在检查文件是否存在和调用 Copy 之间,文件可能会被另一个进程或操作系统删除或重命名。您需要改为使用 try catch。
      • 如果卷相同,这也是 I/O 的巨大浪费,因为移动实际上会在目录信息级别进行重命名。
      • 我正在处理数千个文件并且得到的印象是复制/删除比移动更快。
      • 怎么会有人想出这样的想法。更快或不是至少你正在谋杀磁盘。在问题中说“重命名”应该意味着在本地重命名,这当然不涉及跨分区移动。
      • 使用 File.Move 我遇到了 UnauthorizedAccessException,但是这一系列的复制和删除工作。谢谢!
      【解决方案8】:

      注意:在此示例代码中,我们打开一个目录并搜索文件名中带有左括号和右括号的 PDF 文件。您可以检查和替换您喜欢的名称中的任何字符,或者使用替换函数指定一个全新的名称。

      还有其他方法可以使用此代码进行更精细的重命名,但我的主要目的是展示如何使用 File.Move 进行批量重命名。当我在笔记本电脑上运行它时,这对 180 个目录中的 335 个 PDF 文件有效。这是一时兴起的代码,还有更复杂的方法可以做到这一点。

      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 年前的一个问题的回答完全正确。
      • 这是一个有效的例子。也许矫枉过正,但并非无关紧要。 +1
      • @Adam:这是对三年前已经给出的答案的非常具体的实现,首先是一个与任何具体实现无关的问题。看不出这有什么建设性。
      • @Nyerguds 那么我们对“题外话”有不同的定义,这并不奇怪,因为它是一个主观术语。
      • @Nyerguds 如果它与您无关,那很好。有些人喜欢冗长,因为它可以帮助他们找到“示例/示例”代码的“真实世界”实现。它重命名文件。正如亚当所说,它是如何跑题的,这是主观的。出于某种原因,你觉得它是绝对客观的。哦,好吧,各有各的。无论哪种方式,感谢您的意见。
      【解决方案9】:

      用途:

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

      【讨论】:

      • 如果你要这样做,我建议在做任何事情之前检查'oldFilePath'是否存在......否则你会无缘无故删除'newFilePath'。跨度>
      【解决方案10】:

      用途:

      public static class FileInfoExtensions
      {
          /// <summary>
          /// Behavior when a new filename exists.
          /// </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);
          }
      }
      

      如何使用此代码

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

      【讨论】:

        【解决方案11】:

        没有一个答案提到编写可单元测试的解决方案。您可以使用 System.IO.Abstractions,因为它提供了一个可测试的 FileSystem 操作包装器,您可以使用它来创建模拟文件系统对象并编写单元测试。

        using System.IO.Abstractions;
        
        IFileInfo fileInfo = _fileSystem.FileInfo.FromFileName("filePathAndName");
        fileInfo.MoveTo(Path.Combine(fileInfo.DirectoryName, newName));
        

        已经过测试,它是重命名文件的工作代码。

        【讨论】:

          【解决方案12】:

          我找不到适合我的方法,所以我提出了我的版本。当然,它需要输入和错误处理。

          public void Rename(string filePath, string newFileName)
          {
              var newFilePath = Path.Combine(Path.GetDirectoryName(filePath), newFileName + Path.GetExtension(filePath));
              System.IO.File.Move(filePath, newFilePath);
          }
          

          【讨论】:

            【解决方案13】:

            就我而言,我希望重命名文件的名称是唯一的,因此我在名称中添加了日期时间戳。这样,“旧”日志的文件名始终是唯一的:

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

            【讨论】:

              【解决方案14】:

              Move 也在做同样的事情 = copydelete 旧的。

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

              【讨论】:

              • 是的,如果您只关心最终结果。在内部,没有那么多。
              • 不,移动肯定不会复制和删除。
              【解决方案15】:
              public void RenameFile(string filePath, string newName)
              {
                  FileInfo fileInfo = new FileInfo(filePath);
                  fileInfo.MoveTo(fileInfo.Directory.FullName + "\\" + newName);
              }
              

              【讨论】:

              • 您能解释一下这与其他答案相比有何不同或相关性吗?
              • @Stefan 我只是把它变成了一种干净且可重复使用的方法。所以你可以用最小的依赖来使用它。
              【解决方案16】:
              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);
                  }
              }
              

              【讨论】:

                【解决方案17】:

                我遇到过一种情况,我必须在事件处理程序中重命名文件,这会触发任何文件更改,包括重命名,并且要永远跳过对我必须重命名的文件的重命名,使用:

                1. 制作副本
                2. 删除原件
                File.Copy(fileFullPath, destFileName); // Both have the format of "D:\..\..\myFile.ext"
                Thread.Sleep(100); // Wait for the OS to unfocus the file
                File.Delete(fileFullPath);
                

                【讨论】:

                • 如果您使用 using 块,您可以删除 thread.sleep 并让程序自动取消焦点,对吧?
                • @Zoba,如果您的意思是在File.CopyFile.Delete 静态方法上应用using 块,那么您应该知道这是不可能的,因为它们都返回void。使用using语句,方法(包括构造函数)的返回类型应该是实现IDisposable接口的对象。
                【解决方案18】:
                private static void Rename_File(string FileFullPath, string NewName) // nes name without directory actualy you can simply rename with fileinfo.MoveTo(Fullpathwithnameandextension);
                        {
                            FileInfo fileInfo = new FileInfo(FileFullPath);
                            string DirectoryRoot = Directory.GetParent(FileFullPath).FullName;
                
                            string filecreator = FileFullPath.Substring(DirectoryRoot.Length,FileFullPath.Length-DirectoryRoot.Length);
                             
                            filecreator = DirectoryRoot + NewName;
                            try
                            {
                                fileInfo.MoveTo(filecreator);
                            }
                            catch(Exception ex)
                            {
                                Console.WriteLine(filecreator);
                                Console.WriteLine(ex.Message);
                                Console.ReadKey();
                            }
                
                    enter code here
                            // string FileDirectory = Directory.GetDirectoryRoot()
                
                        }
                

                【讨论】:

                  【解决方案19】:
                  // Source file to be renamed  
                  string sourceFile = @"C:\Temp\MaheshChand.jpg";  
                  // Create a FileInfo  
                  System.IO.FileInfo fi = new System.IO.FileInfo(sourceFile);  
                  // Check if file is there  
                  if (fi.Exists)  
                  {  
                  // Move file with a new name. Hence renamed.  
                  fi.MoveTo(@"C:\Temp\Mahesh.jpg");  
                  Console.WriteLine("File Renamed.");  
                  }  
                  

                  【讨论】:

                    【解决方案20】:

                    用途:

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

                    rename() 函数在stdio.h 头文件中定义。它将文件或目录从 oldname 重命名为 newname。重命名操作与移动相同,因此您也可以使用此功能移动文件。

                    【讨论】:

                    • 欢迎。这个问题是关于使用 C# 语言重命名文件的。我不确定从 C(不是 C#)的标准库中指出一些东西对这里有什么帮助。
                    【解决方案21】:

                    当 C# 没有某些特性时,我使用 C++ 或 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);
                        }
                    }
                    

                    【讨论】:

                    • C#绝对有重命名文件的能力。
                    • 谢谢,这正是我想要的。它可以在可执行文件上更改自己的名称。
                    猜你喜欢
                    • 2015-04-26
                    • 2014-04-04
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-09-03
                    相关资源
                    最近更新 更多