重命名C#中的文件


632

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


我不愿意补充,这里所有的解决方案都存在问题,特别是如果您进行比较并将文件从一个位置移动到另一位置(目录和文件名),只要您应该意识到卷可能是交界点...因此,如果新名称是q:\ SomeJunctionDirectory \ hello.txt,而旧名称是c:\ TargetOfJunctionPoint \ hello.txt ...文件是相同的,但名称却不同。
阿德里安·胡姆

Answers:


966

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

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

12
当文件名仅在字母大小写不同时,此解决方案不起作用。例如file.txt和File.txt
SepehrM 2014年

2
@SepehrM,我只是仔细检查了一下,它在Windows 8.1机器上可以正常工作。
克里斯·泰勒

1
@SepehrM,我没有测试它,但是您指向的示例使用FileInfo.Move而不是File.Move,所以也许与它有关?
克里斯·泰勒

2
@SepehrM Windows文件系统名称不区分大小写。File.txt和file.txt被视为相同的文件名。因此,当您说解决方案不起作用时,我不清楚。您到底在做什么工作不正常?
迈克尔

4
@Michael,文件系统不区分大小写,但是它确实将文件名存储为用户输入的原始大小写。在SepehrM的情况下,他试图更改文件的大小写,由于某种原因,该文件不起作用。不区分大小写的匹配有效。HTH
克里斯·泰勒


47

在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包围它,以避免出现异常。


20
使用这种方法要特别小心...如果目标目录和源目录相同,并且“ newname”实际上是区分大小写的“ oldFileName”版本,则在删除文件之前将其删除。
阿德里安·洪

1
您也不能只检查字符串是否相等,因为有几种表示单个文件路径的方法。
Drew Noakes

File.Move现在有一个重载方法,允许您覆盖文件-File.Move(oldPath,newPath,true)
Ella


34

只需添加:

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
mac10688 '16

31
ew ...使用Path.Combine()而不是组装文件。
阿德里安·嗡嗡

20
  1. 第一个解决方案

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

    您可以创建一个重命名方法来简化它。

  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


8
就是这样,Microsoft.VisualBasic.FileIO.FileSystem.RenameFile调用File.Move。其他感谢规范化原始文件并对参数进行了一些其他错误检查,即。文件存在,文件名不为null等。然后调用File.Move。
克里斯·泰勒

除非Copy()复制所有文件流(我认为不会复制),否则我将避免使用delete / copy。我假设Move()至少在留在同一文件系统上时只是重命名,因此将保留所有文件流。
nickdu '16

“它在网络上发生故障”,那么您将要复制并删除实际上是下载和上传的文件,只是为了节省代码时间。什么样的网络?的Windows共享文件夹(smbftpssh或什么都纷纷命令/图元文件移动/重命名除非不允许(如只读)。
喵喵猫2012年

16

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

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

4
请注意以下内容的任何人:这是反模式,在检查文件是否存在与调用Copy之间,文件可能会被另一个进程或操作系统删除或重命名。您需要改用try catch。
user9993 '16

如果数量相同,这也将浪费大量I / O,因为移动实际上会在目录信息级别进行重命名。
阿德里安·嗡嗡

我正在处理成千上万个文件,并且印象“复制/删除”比“移动”更快。
罗伯托

谁会想到这样的想法。更快或至少不是您正在谋杀磁盘。通过在问题中说“重命名”,它应该意味着本地重命名,这当然不涉及跨分区移动。
喵猫2012年

使用File.Move我遇到了UnauthorizedAccessException,但是复制和删除的这种顺序起作用了。谢谢!
奥利弗·科尼格

6

注意:在此示例代码中,我们打开目录,并在文件名中使用带括号的圆括号搜索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
这个问题完全不对,仅是3年前完全回答了这个问题。
Nyerguds

2
这是一个有效的例子。过度杀伤也许但并非没有意义。+1
亚当

1
@Adam:这是三年前已经给出的答案的非常具体的实现,这个问题最初与任何具体实现无关。看不出这有什么建设性。
Nyerguds 2013年

@Nyerguds然后我们对“在要点之外”有不同的定义,这并不奇怪,因为它是一个主观术语。
亚当

@Nyerguds如果对您不重要,那就很好。有些人喜欢冗长,因为它有助于他们找到“示例/示例”代码的“真实世界”实现。它重命名文件。正如亚当(Adam)所说,这是很主观的。由于某种原因,您认为这是绝对客观的。哦,对了,每个人都有。无论哪种方式,谢谢您的输入。
MicRoc 2014年

6

希望!这将对您有所帮助。:)

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

如何使用此代码?

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

采用:

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
如果要执行此操作,建议您在执行任何操作之前检查'oldFilePath'是否存在...否则,您将无故删除'newFilePath'。
约翰·克罗奇

甚至可以编译(Using System.IO;)吗?
Peter Mortensen

3

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

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


1

我找不到适合自己的方法,所以我提出了我的建议。当然需要输入,错误处理。

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

我遇到一种情况,当我不得不在事件处理程序中重命名文件时,这会触发任何文件更改(包括重命名),并且永远跳过我必须重命名的文件的重命名,方法是:

  1. 复制
  2. 取出原稿
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

以防万一有人会出现这种情况;)


-10

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

20
C#绝对具有重命名文件的能力。
安德鲁·巴伯

76
我无语
克里斯·麦格拉思

谢谢,这正是我想要的。它可以在可执行文件上更改自身名称。
杰克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.