C #에서 파일 이름 바꾸기


632

C #을 사용하여 파일 이름을 바꾸려면 어떻게합니까?


볼륨이 될 수 있다는 것을 알고 있어야하는 한 파일을 한 위치에서 다른 위치 (디렉토리 및 파일 이름)로 이동하고 비교하는 경우 특히 여기의 모든 솔루션에 문제가 있음을 추가하고 싶지 않습니다. junction point ... 따라서 newname이 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
@SepehrM, 방금 두 번 확인했으며 Windows 8.1 컴퓨터에서 제대로 작동합니다.
Chris Taylor

1
@SepehrM, 나는 그것을 테스트하지 않았지만 File.Move가 아닌 FileInfo.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. 사용의 용이성

    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 ()가 모든 파일 스트림을 복사하지 않는 한, 그렇지 않다고 생각하면 삭제 / 복사를 사용하지 않아도됩니다. 적어도 같은 파일 시스템에 머물 때 Move ()는 단순히 이름 바꾸기이므로 모든 파일 스트림이 유지됩니다.
nickdu

"네트워크를 통해 장애가 발생하면"코드 시간의 편의를 위해 실제로 다운로드 및 업로드 할 복사 및 삭제를 수행합니다. 어떤 종류의 네트워크입니까? 윈도우 (공유 폴더 smb) ftp, ssh또는 무엇이든 모든 유무 명령 / 원시 파일 이동 / 허용되지 않는 이름을 변경 (예 : 읽기 전용).
Meow Cat 2012 년

16

파일을 새 파일로 복사 한 다음 System.IO.File클래스를 사용하여 이전 파일을 삭제할 수 있습니다 .

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

4
이 글을 읽는 사람에게주의 사항 : 이것은 안티 패턴이며 파일이 존재하는지 확인한 후 복사 요청 사이에 다른 프로세스 나 OS에 의해 파일이 삭제되거나 이름이 변경 될 수 있습니다. 대신 try catch를 사용해야합니다.
user9993

볼륨이 동일하면 이동이 실제로 디렉토리 정보 레벨에서 이름 바꾸기를 수행하기 때문에 이는 I / O 낭비입니다.
Adrian Hum

수천 개의 파일을 처리하고 있는데 복사 / 삭제가 이동보다 빠릅니다.
Roberto

어떻게 그런 아이디어를 얻을 수 있을까요? 디스크를 살해하는 것이 더 빠르 든 아니든간에. 질문에서 "이름 바꾸기"라고 말하면 로컬 파티션 이름 바꾸기를 의미하며, 어떤 파티션 간 이동도 필요하지 않습니다.
Meow Cat 2012 년

File.Move를 사용하여 UnauthorizedAccessException이 발생했지만이 시퀀스의 복사 및 삭제가 작동했습니다. 감사!
Oliver Konig

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
Adam

1
@Adam : 처음에는 특정 구현에 관한 것이 아니라는 질문에 대해 이미 3 년 전에 주어진 정확한 답변을 매우 구체적으로 구현 한 것입니다. 그것이 어떻게 건설적인지 보지 마십시오.
Nyerguds

@Nyerguds는 우리가 '요점을 넘어서'에 대한 다른 정의를 가지고 있는데, 이것은 주관적인 용어이기 때문에 놀라운 일이 아닙니다.
Adam

@ 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;)합니까?
Peter Mortensen 2016 년

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

이벤트 처리기 내부에서 파일 이름을 바꾸어야하는 경우가 발생했습니다. 이름 바꾸기를 포함한 모든 파일 변경을 트리거하고 파일 이름을 완전히 바꾸지 않고 건너 뛰려면 다음과 같이 이름을 바꿔야합니다.

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

rename () 함수는 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.