เปลี่ยนชื่อไฟล์ใน C #


632

ฉันจะเปลี่ยนชื่อไฟล์โดยใช้ C # ได้อย่างไร


ฉันเกลียดที่จะเพิ่มว่ามีปัญหาที่นี่การแก้ปัญหาทั้งหมดที่นี่โดยเฉพาะอย่างยิ่งถ้าคุณทำการเปรียบเทียบและย้ายไฟล์จากที่หนึ่งไปยังอีกที่หนึ่ง (ไดเรกทอรีและชื่อไฟล์) ตราบเท่าที่คุณควรทราบว่าปริมาณอาจเป็น จุดเชื่อมต่อ ... ดังนั้นหากชื่อใหม่คือ q: \ SomeJunctionDirectory \ hello.txt และชื่อเก่าคือ c: \ TargetOfJunctionPoint \ hello.txt ... ไฟล์เหมือนกัน แต่ไม่มีชื่อ
Adrian Hum

คำตอบ:


966

ลองดูที่System.IO.File.Move "ย้าย" ไฟล์ไปยังชื่อใหม่

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

12
วิธีนี้ไม่ทำงานเมื่อชื่อไฟล์แตกต่างกันในกรณีตัวอักษร ตัวอย่างเช่น file.txt และ File.txt
SepehrM

2
@SehrhrM ฉันเพิ่งตรวจสอบสองครั้งและทำงานได้ดีบนเครื่อง Windows 8.1 ของฉัน
Chris Taylor

1
@SehrhrM ฉันไม่ได้ทดสอบ แต่ตัวอย่างที่คุณชี้ไปที่ใช้ FileInfo.Move และไม่ใช่ File.Move ดังนั้นอาจมีบางสิ่งที่เกี่ยวข้องกับมันหรือไม่
Chris Taylor

2
@SepehrM ชื่อระบบไฟล์ Windows ไม่คำนึงถึงขนาดตัวพิมพ์ File.txt และ file.txt ถือเป็นชื่อไฟล์เดียวกัน ดังนั้นจึงไม่ชัดเจนสำหรับฉันเมื่อคุณพูดว่าวิธีแก้ปัญหาใช้ไม่ได้ คุณกำลังทำอะไรที่ไม่ได้ผล?
Michael

4
@Michael ระบบไฟล์ไม่คำนึงถึงขนาดตัวพิมพ์ แต่จะจัดเก็บชื่อไฟล์ในกรณีดั้งเดิมตามที่ผู้ใช้ป้อน ในกรณีของ SepehrM เขาพยายามเปลี่ยนกรณีของไฟล์ซึ่งด้วยเหตุผลบางอย่างไม่ทำงาน การจับคู่แบบตัวเล็กและตัวเล็กกำลังทำงาน HTH
Chris Taylor


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

หรือล้อมรอบด้วยลองจับเพื่อหลีกเลี่ยงข้อยกเว้น


20
ระวังด้วยวิธีนี้ ... หากไดเรกทอรีปลายทางของคุณและไดเรกทอรีต้นฉบับเหมือนกันและ "newname" จริงๆแล้วเป็นรุ่นที่คำนึงถึงขนาดตัวพิมพ์ของ "oldFileName" คุณจะลบออกก่อนที่คุณจะมีโอกาสย้ายไฟล์ของคุณ
Adrian Hum

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

31
eww ... ใช้ Path.Combine () แทนที่จะรวบรวมไฟล์
Adrian Hum

20
  1. ทางออกแรก

    หลีกเลี่ยงการSystem.IO.File.Moveแก้ปัญหาที่โพสต์ที่นี่ มันล้มเหลวผ่านเครือข่าย อย่างไรก็ตามรูปแบบการคัดลอก / ลบทำงานได้ทั้งในและนอกเครือข่าย ปฏิบัติตามหนึ่งในโซลูชันย้าย แต่แทนที่ด้วยคัดลอกแทน จากนั้นใช้ File.Delete เพื่อลบไฟล์ต้นฉบับ

    คุณสามารถสร้างวิธีการเปลี่ยนชื่อเพื่อให้ง่ายขึ้น

  2. สะดวกในการใช้

    ใช้แอสเซมบลี VB ใน C # เพิ่มการอ้างอิงถึง 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 อื่น ๆ ขอบคุณ normalizing ไฟล์ต้นฉบับและทำการตรวจสอบข้อผิดพลาดเพิ่มเติมเกี่ยวกับข้อโต้แย้งคือ มีไฟล์ชื่อไฟล์ไม่เป็นโมฆะและจะเรียกใช้ File.Move
Chris Taylor

หากไม่มีการคัดลอก () จะเป็นการคัดลอกไฟล์ทั้งหมดที่ฉันคิดว่ามันไม่ได้ใช้ ฉันถือว่า Move () อย่างน้อยเมื่ออยู่ในระบบไฟล์เดียวกันเป็นเพียงการเปลี่ยนชื่อและทำให้ทุกสตรีมไฟล์จะได้รับการดูแล
nickdu

"มันล้มเหลวบนเครือข่าย" จากนั้นคุณจะคัดลอกและลบซึ่งจริงๆแล้วเป็นการดาวน์โหลดและอัปโหลดเพียงเพื่อความสะดวกในการใช้เวลารหัส ... เครือข่ายประเภทใด โฟลเดอร์ (Windows ที่ใช้ร่วมกันsmb) ftp, sshหรือสิ่งที่ทุกคนมีคำสั่ง / วิทยาการสำหรับแฟ้มย้าย / เปลี่ยนชื่อเว้นแต่ไม่ได้รับอนุญาต (เช่นอ่านอย่างเดียว)
แมวเหมียว 2012

16

คุณสามารถคัดลอกเป็นไฟล์ใหม่แล้วลบไฟล์เก่าโดยใช้System.IO.Fileคลาส:

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

4
หมายเหตุสำหรับทุกคนที่อ่านข้อความนี้: นี่เป็นรูปแบบการต่อต้านไฟล์อาจถูกลบหรือเปลี่ยนชื่อโดยกระบวนการอื่นหรือระบบปฏิบัติการระหว่างการตรวจสอบว่ามีอยู่และการเรียกไปคัดลอก คุณต้องลองใช้ catch catch แทน
user9993

หากปริมาตรเท่ากันนี่ก็เป็นการสิ้นเปลืองของ I / O อย่างมากเนื่องจากการย้ายจะทำการเปลี่ยนชื่อที่ระดับข้อมูลไดเรกทอรี
Adrian Hum

ฉันกำลังประมวลผลไฟล์หลายพันไฟล์และได้รับความประทับใจ Copy / Delete เร็วกว่าการย้าย
โรแบร์โต

ทุกคนจะคิดอย่างไรกับแนวคิดนี้ เร็วกว่าหรือไม่อย่างน้อยคุณกำลังฆ่าดิสก์ โดยการพูดว่า "เปลี่ยนชื่อ" ในคำถามก็ควรหมายถึงการเปลี่ยนชื่อในพื้นที่ซึ่งแน่นอนว่าไม่มีการย้ายข้ามพาร์ติชัน
แมวเหมียว 2012

ด้วย File.Move ฉันพบว่า UnauthorizedAccessException แต่ลำดับการคัดลอกและลบนี้ใช้ได้ ขอบคุณ!
Oliver Konig

6

หมายเหตุ:ในรหัสตัวอย่างนี้เราเปิดไดเรกทอรีและค้นหาไฟล์ PDF ด้วยวงเล็บเปิดและปิดในชื่อของไฟล์ คุณสามารถตรวจสอบและแทนที่ตัวอักษรใด ๆ ในชื่อที่คุณชอบหรือเพียงแค่ระบุชื่อใหม่โดยใช้ฟังก์ชั่นแทนที่

มีวิธีอื่นในการทำงานจากรหัสนี้เพื่อทำการเปลี่ยนชื่ออย่างละเอียดมากขึ้น แต่ความตั้งใจหลักของฉันคือการแสดงวิธีการใช้ File.Move เพื่อทำการเปลี่ยนชื่อชุด สิ่งนี้ใช้ได้กับไฟล์ PDF 335 ไฟล์ใน 180 ไดเรกทอรีเมื่อฉันใช้งานบนแล็ปท็อปของฉัน นี่คือการกระตุ้นของรหัสช่วงเวลาและมีวิธีการทำอย่างละเอียดมากขึ้น

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
มันเป็นตัวอย่างที่ถูกต้อง overkill อาจ แต่ไม่ข้างจุด +1
อดัม

1
@ อดัม: เป็นการใช้งานที่เฉพาะเจาะจงมากกับคำตอบที่ได้รับเมื่อสามปีก่อนในคำถามที่ไม่เกี่ยวกับการใช้งานเฉพาะในตอนแรก ไม่เห็นว่ามีวิธีการใด ๆ ที่สร้างสรรค์
Nyerguds

@ Nyerguds จากนั้นเรามีคำจำกัดความที่แตกต่างกันของ 'ข้างจุด' ซึ่งไม่น่าแปลกใจเพราะมันเป็นคำอัตนัย
อดัม

@ Nyerguds ถ้ามันไม่เกี่ยวข้องกับคุณแล้วมันก็โอเค บางคนชอบการใช้คำฟุ่มเฟื่อยเพราะช่วยให้พวกเขาค้นหาการใช้งาน "รหัส" ตัวอย่าง / ตัวอย่าง " มันเปลี่ยนชื่อไฟล์ มันอยู่ข้างจุดนี้อย่างไรอย่างที่อดัมพูด ด้วยเหตุผลบางอย่างคุณรู้สึกว่ามันมีวัตถุประสงค์อย่างแน่นอน ดีสำหรับเขาแต่ละคน ขอบคุณสำหรับการป้อนข้อมูลทั้งสองวิธี
MicRoc

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' โดยไม่มีเหตุผล
John Kroetch

นั่นแม้แต่คอมไพล์ ( Using System.IO;) หรือไม่?
ปีเตอร์มอร์เทนเซ่น

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

2

การย้ายทำสิ่งเดียวกัน = คัดลอกและลบอันเก่า

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

1
จริงถ้าสิ่งที่คุณใส่ใจคือผลลัพธ์สุดท้าย ภายในไม่มาก
Michael

ไม่ย้ายแน่นอนที่สุดไม่ได้คัดลอกและลบ
Jim Balter

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

ฉันพบกรณีเมื่อฉันต้องเปลี่ยนชื่อไฟล์ใน event handler ซึ่งเรียกการเปลี่ยนแปลงไฟล์ใด ๆ รวมถึงการเปลี่ยนชื่อและข้ามการเปลี่ยนชื่อไฟล์ตลอดไปฉันต้องเปลี่ยนชื่อใหม่ด้วย:

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

ในกรณีที่มีใครบางคนจะมีสถานการณ์เช่นนี้;)


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

เปลี่ยนชื่อฟังก์ชั่น () กำหนดไว้ในไฟล์ส่วนหัว stdio.h เปลี่ยนชื่อไฟล์หรือไดเรกทอรีจาก oldname เป็น newname การดำเนินการเปลี่ยนชื่อเหมือนกับย้ายดังนั้นคุณสามารถใช้ฟังก์ชันนี้เพื่อย้ายไฟล์


ยินดีต้อนรับ คำถามนี้เกี่ยวกับการเปลี่ยนชื่อไฟล์โดยใช้ภาษา C # ฉันไม่แน่ใจว่าการชี้ให้เห็นบางสิ่งจากไลบรารีมาตรฐานของ C (ไม่ใช่ C #) ช่วยได้ที่นี่
Jeff Dammeyer

-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 # มีความสามารถในการเปลี่ยนชื่อไฟล์อย่างแน่นอน
Andrew Barber เมื่อ

76
ฉันพูดไม่ได้
Chris McGrath

ขอบคุณนี่คือสิ่งที่ฉันต้องการ มันสามารถเปลี่ยนชื่อตัวเองในไฟล์ที่ปฏิบัติการได้
Jake
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.