Đổi tên một tệp trong C #


632

Làm cách nào để đổi tên tệp bằng C #?


Tôi ghét phải thêm rằng có một vấn đề ở đây, tất cả các giải pháp ở đây đặc biệt là nếu bạn so sánh và đang di chuyển tệp từ vị trí này sang vị trí khác (thư mục cũng như tên tệp) trong chừng mực vì bạn nên biết rằng một khối lượng có thể là một điểm giao nhau ... vì vậy nếu tên mới là q: \ someJeftDirectory \ hello.txt và tên cũ là c: \ TargetOfJeftPoint \ hello.txt ... các tệp giống nhau nhưng tên không giống nhau.
Adrian Hum

Câu trả lời:


966

Hãy xem System.IO.File.Move , "di chuyển" tệp sang một tên mới.

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

12
Giải pháp này không hoạt động khi tên tệp chỉ khác nhau trong trường hợp chữ cái. Ví dụ: file.txt và File.txt
SepehrM

2
@SepehrM, tôi chỉ cần kiểm tra hai lần và nó hoạt động tốt trên máy Windows 8.1 của tôi.
Chris Taylor

1
@SepehrM, tôi đã không kiểm tra nó, nhưng các mẫu bạn trỏ đến để sử dụng FileInfo.Move và không phải File.Move vì vậy có lẽ điều đó có liên quan?
Chris Taylor

2
@SepehrM Tên hệ thống tệp Windows không phân biệt chữ hoa chữ thường. File.txt và file.txt được coi là cùng một tên tệp. Vì vậy, nó không rõ ràng với tôi khi bạn nói giải pháp không hoạt động. Bạn đang làm gì chính xác mà không làm việc?
Michael

4
@Michael, hệ thống tệp không phân biệt chữ hoa chữ thường, nhưng nó lưu tên tệp trong trường hợp gốc do người dùng nhập vào. Trong trường hợp của SepehrM, anh ta đã cố gắng thay đổi trường hợp của một tập tin, vì lý do nào đó không hoạt động. Các trường hợp phù hợp không nhạy cảm đã làm việc. HTH
Chris Taylor


47

Trong phương thức File.Move, điều này sẽ không ghi đè lên tệp nếu nó đã tồn tại. Và nó sẽ ném một ngoại lệ.

Vì vậy, chúng ta cần kiểm tra xem tập tin có tồn tại hay không.

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

Hoặc bao quanh nó bằng một cái bẫy thử để tránh một ngoại lệ.


20
hãy thực sự cẩn thận với cách tiếp cận này ... nếu thư mục đích và thư mục nguồn của bạn giống nhau và "newname" thực sự là phiên bản phân biệt chữ hoa chữ thường của "oldFileName", bạn sẽ xóa trước khi có cơ hội di chuyển tệp của mình.
Adrian Hum

1
Bạn cũng không thể chỉ kiểm tra các chuỗi cho sự bằng nhau vì có một số cách biểu diễn một đường dẫn tệp duy nhất.
Drew Noakes

File.Move hiện có một phương thức quá tải cho phép bạn ghi đè lên tệp - File.Move (oldPath, newPath, true)
Ella


34

Chỉ cần thêm:

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

Và sau đó...

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

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

31
eww ... Sử dụng Path.Combine () thay vì lắp ráp tệp.
Adrian Hum

20
  1. Giải pháp đầu tiên

    Tránh System.IO.File.Movecác giải pháp được đăng ở đây (bao gồm câu trả lời). Nó thất bại trên các mạng. Tuy nhiên, sao chép / xóa mẫu hoạt động cục bộ và qua mạng. Thực hiện theo một trong các giải pháp di chuyển, nhưng thay thế bằng Sao chép thay thế. Sau đó sử dụng File.Delete để xóa tệp gốc.

    Bạn có thể tạo một phương thức Đổi tên để đơn giản hóa nó.

  2. Dễ sử dụng

    Sử dụng lắp ráp VB trong C #. Thêm tham chiếu đến Microsoft.VisualBasic

    Sau đó đổi tên tập tin:

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

    Cả hai đều là chuỗi. Lưu ý rằng myfile có đường dẫn đầy đủ. Tên mới không. Ví dụ:

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

    Các C:\whatever\thư mục sẽ chứa b.txt.


8
chỉ để bạn biết, Microsoft.VisualBasic.FileIO.FileSystem.RenameFile gọi File.Move. Cảm ơn khác bình thường hóa tệp gốc và thực hiện một số kiểm tra lỗi bổ sung trên các đối số tức là. tệp tồn tại, tên tệp không null, vv sau đó gọi File.Move.
Chris Taylor

Trừ khi Copy () sao chép tất cả các luồng tệp mà tôi cho là không có, tôi sẽ tránh sử dụng xóa / sao chép. Tôi giả sử Move (), ít nhất là khi ở trên cùng một hệ thống tệp, chỉ đơn giản là đổi tên và do đó tất cả các luồng tệp sẽ được duy trì.
nickdu

"Nó không thành công trên mạng", sau đó bạn sẽ sao chép và xóa, đây thực sự là tải xuống và tải lên, chỉ để thuận tiện cho thời gian mã ... Loại mạng nào? Cửa sổ thư mục chia sẻ ( smb), ftp, sshhoặc bất cứ điều gì tất cả có các lệnh / nguyên thủy cho tập tin di chuyển / đổi tên trừ khi không được phép (ví dụ read-only).
Mèo Meow 2012

16

Bạn có thể sao chép nó dưới dạng tệp mới và sau đó xóa tệp cũ bằng System.IO.Filelớp:

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

4
Lưu ý cho bất cứ ai đọc điều này: Đây là một mô hình chống, tệp có thể bị xóa hoặc đổi tên bởi một quy trình khác hoặc HĐH giữa kiểm tra nếu nó tồn tại và cuộc gọi của bạn để Sao chép. Thay vào đó, bạn cần sử dụng một thử bắt.
dùng9993

Nếu âm lượng là như nhau, đây cũng là một sự lãng phí rất lớn đối với I / O vì một động thái thực sự sẽ đổi tên ở cấp thông tin thư mục.
Adrian Hum

Tôi đang xử lý hàng ngàn tệp và có ấn tượng Sao chép / Xóa nhanh hơn Di chuyển.
Roberto

Làm thế nào bất cứ ai sẽ đưa ra một ý tưởng như vậy. Nhanh hơn hoặc không ít nhất là bạn đang giết đĩa. Bằng cách nói "đổi tên" trong câu hỏi, điều đó có nghĩa là đổi tên cục bộ, điều này tất nhiên không liên quan đến việc di chuyển phân vùng chéo.
Mèo Meow 2012

với File.Move tôi đã chạy vào UnlegAccessException, nhưng chuỗi Sao chép và Xóa này đã hoạt động. Cảm ơn!
Oliver Konig

6

GHI CHÚ: Trong mã ví dụ này, chúng tôi mở một thư mục và tìm kiếm các tệp PDF với dấu ngoặc đơn mở và đóng trong tên của tệp. Bạn có thể kiểm tra và thay thế bất kỳ ký tự nào trong tên bạn thích hoặc chỉ định một tên hoàn toàn mới bằng cách sử dụng các chức năng thay thế.

Có nhiều cách khác để làm việc từ mã này để thực hiện các đổi tên phức tạp hơn nhưng mục đích chính của tôi là chỉ ra cách sử dụng File.Move để thực hiện đổi tên hàng loạt. Điều này đã làm việc với 335 tệp PDF trong 180 thư mục khi tôi chạy nó trên máy tính xách tay của mình. Đây là sự thúc đẩy của mã thời điểm và có nhiều cách phức tạp hơn để làm điều đó.

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
Đó là ... hoàn toàn bên cạnh vấn đề, về một câu hỏi đã trả lời chính xác đến thời điểm 3 năm trước.
Nyerguds

2
Đó là một ví dụ hợp lệ. Quá mức có thể nhưng không bên cạnh điểm. +1
Adam

1
@Adam: đó là một triển khai rất cụ thể của chính xác câu trả lời đã được đưa ra ba năm trước, về một câu hỏi không phải là về bất kỳ triển khai cụ thể nào ở nơi đầu tiên. Đừng thấy cách đó mang tính xây dựng.
Nyerguds

@Nyerguds sau đó chúng tôi có các định nghĩa khác nhau về 'bên cạnh điểm', điều này không đáng ngạc nhiên vì đó là một thuật ngữ chủ quan.
Adam

@Nyerguds nếu nó không liên quan đến bạn thì cũng không sao. Một số người thích sự dài dòng vì nó giúp họ tìm ra các triển khai "mẫu / ví dụ" trong thế giới thực. Nó đổi tên tập tin. Làm thế nào nó bên cạnh quan điểm là khá nhiều như Adam nói, đó là chủ quan. Đối với một số lý do bạn cảm thấy nó là hoàn toàn khách quan. Oh tốt, để mỗi của riêng mình. Cảm ơn cho đầu vào, một trong hai cách.
MicRoc

6

Hy vọng! nó sẽ hữu ích cho bạn :)

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

Làm thế nào để sử dụng mã này?

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

Sử dụng:

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
Nếu bạn định làm điều này, tôi khuyên bạn nên kiểm tra rằng 'oldFilePath' tồn tại trước khi làm bất cứ điều gì ... nếu không bạn sẽ xóa 'newFilePath' mà không có lý do.
John Kroetch

Điều đó thậm chí còn biên dịch ( Using System.IO;)?
Peter Mortensen

3

Trong trường hợp của tôi, tôi muốn tên của tệp được đổi tên là duy nhất, vì vậy tôi thêm dấu thời gian vào tên. Bằng cách này, tên tệp của nhật ký 'cũ' luôn là duy nhất:

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

Di chuyển đang làm tương tự = Sao chép và xóa cái cũ.

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

1
Đúng, nếu tất cả những gì bạn quan tâm là kết quả cuối cùng. Trong nội bộ, không quá nhiều.
Michael

Không, Di chuyển chắc chắn không Sao chép và Xóa.
Jim Balter

1

Tôi không thể tìm thấy phương pháp phù hợp với mình, vì vậy tôi đề xuất phiên bản của mình. Tất nhiên cần đầu vào, xử lý lỗi.

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

Tôi đã gặp phải một trường hợp khi tôi phải đổi tên tệp bên trong trình xử lý sự kiện, điều này đã kích hoạt bất kỳ thay đổi tệp nào, bao gồm đổi tên và bỏ qua việc đổi tên mãi mãi tệp mà tôi phải đổi tên, với:

  1. Tạo bản sao của nó
  2. Xóa bản gốc
File.Copy(fileFullPath, destFileName); // both has the format of "D:\..\..\myFile.ext"
Thread.Sleep(100); // wait OS to unfocus the file 
File.Delete(fileFullPath);

Chỉ trong trường hợp nếu ai đó, sẽ có kịch bản như vậy;)


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

Hàm rename () được định nghĩa trong tệp tiêu đề stdio.h. Nó đổi tên một tập tin hoặc thư mục từ tên cũ thành tên mới. Thao tác đổi tên cũng giống như di chuyển, do đó bạn cũng có thể sử dụng chức năng này để di chuyển tệp.


Chào mừng bạn Câu hỏi này là về việc đổi tên một tệp bằng ngôn ngữ C #. Tôi không chắc việc chỉ ra một cái gì đó từ thư viện chuẩn của C (không phải C #) sẽ giúp gì ở đây.
Jeff Dammeyer

-10

Khi C # không có một số tính năng, tôi sử dụng C ++ hoặ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 # hoàn toàn có khả năng đổi tên tập tin.
Andrew Barber

76
Tôi không nói nên lời
Chris McGrath

Cảm ơn, đây chính xác là những gì tôi muốn. Nó có thể thay đổi tên tự trên một tập tin thực thi.
Jake
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.