CodeGym /행동 /C# SELF /파일과 디렉터리 이동

파일과 디렉터리 이동

C# SELF
레벨 40 , 레슨 3
사용 가능

1. 소개

파일 이동 작업이 필요한 시나리오는 엄청 많아요: 임시 폴더에서 "다운로드된" 파일을 문서 폴더로 옮기기, 사진 대량 정리, 패턴에 따른 파일 이름 변경, 메일이나 로그 정리 등. 파일 시스템은 정리를 좋아해요 — 아니면 적어도 그럴 듯한 상태를. 그리고 좋은 개발자는 그런 정리를 잘할 줄 알아야 합니다.

또한 이런 과제는 면접에서 자주 나와요: "모든 파일에 버전 번호를 붙여서 이름을 바꾸는 유틸리티를 만들어라" 또는 "오래된 문서를 아카이브로 옮기는 커맨드를 만들어라" 같은 식으로요. 그럼 C#에서 어떻게 하는지 같이 보죠.

기능 개요

.NET에는 이동과 이름 변경을 위한 두 가지 주요 방법이 있어요 — 정적 메서드(File.Move, Directory.Move)를 사용하거나 인스턴스 메서드(FileInfo.MoveTo, DirectoryInfo.MoveTo)를 사용하는 거예요. 내부적으로는 거의 같은 일을 하고, 주로 문법 차이만 있어요.

.NET은 이동과 이름 바꾸기를 어떻게 "보는"가?

주의! 이름 변경과 이동은 본질적으로 같은 작업이에요: 파일이나 폴더는 경로로 식별됩니다. 경로가 바뀌면 객체는 "이동"되거나 "이름이 바뀐" 것으로 간주돼요. 같은 디렉터리에서 이름만 바꾸면 이름 변경이고, 전체 경로를 바꾸면 이동입니다. 슈뢰딩거의 상자처럼, 새 경로에 새 이름을 주면 둘 다 해당될 수 있어요!

2. 파일 이동 및 이름 변경: 예제

간단한 것부터 복잡한 것까지 차근차근 진행할게요. 예제는 미니 파일 매니저를 기준으로 할게요.

정적 메서드 File.Move

파일을 이동(또는 이름 변경)하는 예제입니다:


// 파일 test1.txt를 다른 폴더로 새 이름으로 이동
File.Move(@"C:\Temp\test1.txt", @"C:\Archive\test1_archived.txt");

같은 폴더에서 단순히 이름만 바꾸고 싶다면:


// 파일 이름만 변경
File.Move(@"C:\Temp\test1.txt", @"C:\Temp\test_renamed.txt");

이게 전부예요! .NET은 한 경로를 제거하고 다른 경로를 객체에 "할당"한다고 보면 됩니다 — 두 경로에 접근 권한이 있고 충돌이 없으면 동작해요.

정적 메서드 Directory.Move

폴더도 마찬가지예요:


// 폴더 이동
Directory.Move(@"C:\Temp\OldFolder", @"C:\Temp\NewFolder");

같은 디렉터리에서 이름만 바꾸거나 다른 위치로 통째로 옮길 수 있어요.

3. 인스턴스 메서드: FileInfo.MoveToDirectoryInfo.MoveTo

이미 FileInfoDirectoryInfo 객체가 있다면, MoveTo()를 호출할 수 있어요:


var fileInfo = new FileInfo(@"C:\Temp\test1.txt");
fileInfo.MoveTo(@"C:\Archive\test1_archived.txt");

// 폴더:
var dirInfo = new DirectoryInfo(@"C:\Temp\OldFolder");
dirInfo.MoveTo(@"C:\Temp\NewFolder");

여기서도 새 경로가 같은 디렉터리의 다른 이름이면 이름 변경, 다른 디렉터리면 이동으로 동작합니다.

4. 목적지에 이미 파일이 있다면?

바로 이 지점에서 골치 아픈 경우가 자주 발생해요.

File.Move

목적지 경로에 이미 파일이 있으면 IOException이 발생해서 코드가 예외로 종료됩니다:


try
{
    File.Move("data.txt", "archive\\data.txt");
}
catch (IOException ex)
{
    Console.WriteLine("목적지에 파일이 이미 존재합니다! " + "ex.Message");
}

FileInfo.MoveTo

똑같아요 — 목적지에 파일이 있으면 IOException이 발생합니다.

Directory.Move

폴더의 경우는 더 엄격해요: 대상 폴더가 이미 존재하면 예외가 납니다. 이미 차지된 폴더로는 이동할 수 없어요.

교훈: 이동하기 전에 항상 대상에 동일한 파일이나 폴더가 있는지 확인하세요!


// 대상 경로에 파일이 있는지 안전하게 확인
if (!File.Exists("archive\\data.txt"))
{
    File.Move("data.txt", "archive\\data.txt");
}
else
{
    Console.WriteLine("목적지에 파일이 이미 존재합니다!");
}

5. 유용한 팁

폴더 이름 변경 예제


var oldDir = @"C:\Projects\OldReport";
var newDir = @"C:\Projects\NewReport";

// 새 폴더가 없고 기존 폴더가 있으면 이름 변경
if (Directory.Exists(oldDir) && !Directory.Exists(newDir))
{
    Directory.Move(oldDir, newDir);
    Console.WriteLine("폴더 이름이 성공적으로 변경되었습니다.");
}
else
{
    Console.WriteLine("오류: 원본 폴더가 없거나 새 폴더가 이미 존재합니다.");
}

하위 내용까지 고려한 이름 변경

폴더의 모든 내용(하위 폴더, 파일)은 추가 작업 없이 함께 이동됩니다! 편하죠: 한 번에 계층 전체가 옮겨집니다.

베스트 프랙티스와 Path 클래스의 유용한 메서드

파일 이름 변경이나 경로 조작할 때는 System.IO.Path의 메서드들을 사용해서 안전하게 새 경로를 만들거나 파일 이름을 바르세요:

  • 확장자를 제외한 파일 이름 얻기: Path.GetFileNameWithoutExtension(path)
  • 확장자만 바꾸기: Path.ChangeExtension(path, ".bak")
  • 다른 이름으로 새 경로 만들기: Path.Combine(Path.GetDirectoryName(path), "newname.txt")

string oldPath = @"C:\Reports\2023_Final.docx";
string newName = "2023_Archive.docx";
string newPath = Path.Combine(Path.GetDirectoryName(oldPath)!, newName);

File.Move(oldPath, newPath);

6. 중요한 주의점과 흔한 실수

권한과 잠금

경로 중 하나에 쓰기 권한이 없으면 UnauthorizedAccessException이 발생합니다. 마찬가지로 파일이 다른 프로세스에서 사용 중(예: Word로 열려 있음)이면 오류가 납니다. 아주 흔한 상황이에요.

다른 드라이브나 볼륨 간 이동

기본적으로 File.Move는 같은 볼륨/드라이브 내에서 빠른 이름 변경 동작을 수행합니다. C 드라이브에서 D 드라이브로 파일을 옮기면 .NET은 내부적으로 복사 후 원본 삭제를 수행해요. 만약 대상 드라이브가 용량 부족 등으로 실패하면 원본은 그대로 남습니다.

흥미로운 점: 대부분의 현대 파일 시스템은 같은 볼륨 내에서는 "빠른 이름 변경/이동"을 지원하고, 볼륨 간 이동은 복사+삭제 방식으로 이뤄집니다.

폴더 자체 이동 (Directory.Move)

폴더를 자기 자신 내부나 그 하위 폴더로 이동하려 하면 안 됩니다 (예: C:\DataC:\Data\Archive로 이동) — 오류가 납니다.

안전하게 이동하려면?

특히 대량으로 이동할 때는, 항상 소스 존재 여부(File.Exists, Directory.Exists)와 대상 충돌 여부를 확인하세요. 그리고 try-catch를 잊지 마세요: 파일 시스템은 변덕스러울 수 있어 언제든 오류를 던질 수 있습니다.

2
과제
C# SELF, 레벨 40, 레슨 3
잠금
모든 파일을 한 폴더에서 다른 폴더로 이동하기
모든 파일을 한 폴더에서 다른 폴더로 이동하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION