CodeGym /행동 /C# SELF /인스턴스 클래스 FileInfo 와...

인스턴스 클래스 FileInfoDirectoryInfo

C# SELF
레벨 39 , 레슨 1
사용 가능

1. 소개

정적 클래스들, 예를 들어 FileDirectory 는 만능 스위스 아미 나이프처럼 항상 손에 닿는 도구라 빠르게 문제를 해결하지만 특정 객체에 묶여있지 않아요. 반면 FileInfoDirectoryInfo 는 특정 파일이나 폴더를 위해 만들어진 개인화된 도구에 가깝습니다. 특정 객체에 대해 많은 정보를 알고 있고, 동일 객체에 대한 반복 작업에서 더 편리하고 유연하게 동작하죠.

인스턴스 클래스 는 특정 파일 시스템 객체에 대한 세부 정보를 보관합니다. 처음 속성을 로드한 이후에는(객체가 오래되지 않았다면) 다시 파일 시스템을 쿼리할 필요가 없을 수 있어요.

  • FileInfo — 특정 파일 작업용.
  • DirectoryInfo — 특정 디렉터리(폴더) 작업용.

이들은 파일/폴더의 자세한 정보(크기, 생성일, 확장자, 사용 가능한 속성 등)를 얻고 파일/폴더를 복사, 삭제, 이동 등 다양한 작업을 수행할 수 있는 속성과 메서드를 포함합니다.

FileInfoDirectoryInfo 구조

두 클래스는 공통 추상 클래스인 FileSystemInfo 를 상속하므로 파일과 폴더를 동일한 방식으로 다루는 코드를 작성할 수 있습니다.


System.Object
   |
System.MarshalByRefObject
   |
System.IO.FileSystemInfo (추상 클래스)
   |             |
  FileInfo    DirectoryInfo

언제 인스턴스 클래스를 사용할까?

  • 하나의 파일/폴더에 대해 많은 정보(크기, 수정일, 확장자, 속성 등)를 여러 번 사용해야 할 때.
  • 디렉터리의 모든 파일/폴더를 순회하면서 각 객체를 '살아있는' 인스턴스로 다루고 싶을 때.
  • 파일 시스템에 불필요하게 여러 번 접근하지 않는 것이 성능상 중요할 때(캐싱).
  • 객체지향적인 코드 스타일(백업, 미디어 라이브러리, 파일 매니저 등)을 선호할 때.

FileInfo 또는 DirectoryInfo 인스턴스 생성 방법

using System.IO;

// 기존(또는 아직 없는!) 파일에 대한 FileInfo 객체 생성:
var fileInfo = new FileInfo("notes.txt");

// 폴더에 대한 DirectoryInfo 객체 생성:
var dirInfo = new DirectoryInfo(@"C:\Projects");

// 상대경로나 절대경로 모두 사용 가능!

중요: FileInfo 또는 DirectoryInfo 객체를 생성한다고 해서 파일/폴더가 실제로 생성되는 것은 아닙니다. 단지 기술(참조)일 뿐이에요.

2. FileInfo 작업

이 클래스의 주요 속성과 메서드를 정리해봅시다. 참고용 메모:

속성/메서드 반환 내용 사용 예
Name
파일 이름
fileInfo.Name
FullName
전체 경로
fileInfo.FullName
Length
파일 크기(바이트)
fileInfo.Length
Directory
부모 디렉터리 (DirectoryInfo)
fileInfo.Directory.FullName
Exists
파일이 실제로 존재하는지?
fileInfo.Exists
Extension
파일 확장자(.txt 등)
fileInfo.Extension
CreationTime
생성일
fileInfo.CreationTime
LastWriteTime
최종 수정일
fileInfo.LastWriteTime
IsReadOnly
읽기 전용 여부
fileInfo.IsReadOnly
메서드
CopyTo()
파일 복사
fileInfo.CopyTo("copy.txt")
Delete()
파일 삭제
fileInfo.Delete()
MoveTo()
파일 이동
fileInfo.MoveTo("move.txt")
OpenRead()
읽기용 스트림 열기
using var stream = fileInfo.OpenRead()
OpenWrite()
쓰기용 스트림 열기
using var stream = fileInfo.OpenWrite()

예제: 파일 정보 얻기

간단한 모듈을 추가해서 FileInfo 로 파일의 상세 정보를 얻어봅시다.

Console.WriteLine("파일 이름을 입력하세요:");
string fileName = Console.ReadLine();

var file = new FileInfo(fileName);
if (file.Exists)
{
    Console.WriteLine($"파일 이름: {file.Name}");
    Console.WriteLine($"경로: {file.FullName}");
    Console.WriteLine($"크기: {file.Length} 바이트");
    Console.WriteLine($"확장자: {file.Extension}");
    Console.WriteLine($"생성일: {file.CreationTime}");
    Console.WriteLine($"마지막 수정: {file.LastWriteTime}");

    // 추가: 부모 디렉터리 표시
    Console.WriteLine($"부모 폴더: {file.DirectoryName}");
}
else
{
    Console.WriteLine("파일을 찾을 수 없습니다.");
}

주의: 파일 내용을 읽는 것이 아니라 메타정보만 가져옵니다.

연습: 파일 복사 및 삭제

// ... 메인 메서드 내부에서 파일 정보 출력이 성공한 뒤:
Console.WriteLine("복사할 경로를 입력하세요:");
string copyPath = Console.ReadLine();

try
{
    file.CopyTo(copyPath);
    Console.WriteLine($"파일이 {copyPath} 로 성공적으로 복사되었습니다.");
}
catch (IOException ex)
{
    Console.WriteLine($"파일을 복사할 수 없습니다: {ex.Message}");
}

// 이제 복사본을 삭제해볼게요
Console.WriteLine("복사본을 삭제하시겠습니까? (y/n):");
if (Console.ReadLine().Trim().ToLower() == "y")
{
    var copyFile = new FileInfo(copyPath);
    if (copyFile.Exists)
    {
        copyFile.Delete();
        Console.WriteLine("복사본이 삭제되었습니다.");
    }
}

3. DirectoryInfo 작업

DirectoryInfo 가 제공하는 기능들을 살펴봅시다:

속성/메서드 반환 내용 사용 예
Name
폴더 이름
dirInfo.Name
FullName
전체 경로
dirInfo.FullName
Parent
부모 폴더 (DirectoryInfo)
dirInfo.Parent.FullName
Exists
폴더가 존재하는지?
dirInfo.Exists
CreationTime
생성일
dirInfo.CreationTime
LastWriteTime
수정일
dirInfo.LastWriteTime
메서드
Create()
폴더 생성
dirInfo.Create()
Delete()
폴더 삭제
dirInfo.Delete()
GetFiles()
파일 배열 (FileInfo 배열)
dirInfo.GetFiles()
GetDirectories()
하위 폴더 배열 (DirectoryInfo 배열)
dirInfo.GetDirectories()
EnumerateFiles()
파일 열거 (IEnumerable<FileInfo>, 지연 모드)
dirInfo.EnumerateFiles()
MoveTo()
폴더 이동
dirInfo.MoveTo("path")

예제: 파일과 폴더 순회

Console.WriteLine("폴더 경로를 입력하세요:");
string path = Console.ReadLine();

var dir = new DirectoryInfo(path);
if (!dir.Exists)
{
    Console.WriteLine("폴더를 찾을 수 없습니다!");
    return;
}

Console.WriteLine("\n--- 파일 ---");
foreach (var file in dir.GetFiles())
{
    Console.WriteLine($"{file.Name} ({file.Length} 바이트)");
}

Console.WriteLine("\n--- 하위 폴더 ---");
foreach (var subDir in dir.GetDirectories())
{
    Console.WriteLine(subDir.Name);
}

4. 유용한 팁

정적 메서드 vs 인스턴스 클래스

어떤 접근법을 쓸지 결정할 때: 한 번만 하는 '일회성' 동작이면 File.Exists(path) 또는 File.ReadAllText(path) 같은 정적 메서드가 더 간단하고 약간 더 빠릅니다. 오버헤드가 적기 때문이죠.

반면 파일/폴더에 대해 많은 정보를 얻거나 반복 연산을 해야 하거나 OOP 스타일로 코드를 쓰고 싶다면 FileInfoDirectoryInfo 같은 인스턴스가 더 적합합니다.

두 접근법은 내부적으로 유사한 저수준 시스템 호출을 사용합니다. 하지만 인스턴스 클래스는 일부 속성(크기, 날짜, 속성 등)을 캐시해서 파일 시스템 접근 횟수를 줄여줍니다 — 특히 많은 파일을 순회할 때 유리합니다.

날짜/시간 처리에 관해

속성 CreationTime, LastWriteTime, LastAccessTimeDateTime 형식을 반환합니다.

Console.WriteLine($"파일 생성: {file.CreationTime:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine($"마지막 수정: {file.LastWriteTime:yyyy-MM-dd HH:mm:ss}");

만약 파일이나 폴더가 인스턴스 생성 후 디스크에서 변경되었다면 캐시된 정보가 오래될 수 있습니다. 이 경우 file.Refresh() 를 호출해서 정보를 갱신하세요.

실용적인 조언

  • 인스턴스 클래스는 파일 시스템 래퍼(백업, 미디어 라이브러리, 인덱서 등)를 만들 때 편리합니다.
  • LINQ 와 함께 사용하면 크기, 날짜, 확장자 등으로 필터링 후 선택한 객체에 작업을 수행하기 좋습니다.
  • 대량 작업 시에는 EnumerateFiles()EnumerateDirectories()GetFiles()/GetDirectories() 보다 선호하세요 — 지연 열거가 메모리를 절약하고 처리 시작 속도를 높입니다.

정적 방법과 인스턴스 방식 비교

정적 메서드 인스턴스 클래스
문법
File.Delete(path)
new FileInfo(path).Delete()
캐싱 없음 있음
많은 정보 필요 여부 여러 메서드를 호출해야 함 객체에 포함되어 있음
OOP 스타일 아님
대량 작업 불편 편리
스트림 작업 가능 가능

정보와 객체 갱신

FileInfo / DirectoryInfo 객체는 처음 속성에 접근할 때 값을 캐시합니다. 만약 인스턴스 생성 이후 파일/폴더가 디스크에서 변경되었다면 .Refresh() 를 호출해 정보를 갱신하세요.

var file = new FileInfo("notes.txt");
long oldSize = file.Length;

// 이 사이에 파일이 외부에서 변경될 수 있음

file.Refresh();
long newSize = file.Length;

파일 시스템을 감시하는 프로그램을 만드는 경우 이 메커니즘이 중요합니다.

5. 인스턴스 클래스 사용 시 흔한 실수

오해: new FileInfo("file.txt") 를 하면 파일이 이미 존재한다고 생각하는 것. 실제로는 그렇지 않습니다 — 파일은 명시적으로 쓰거나 Create() 를 호출해야 생깁니다.

존재하지 않는 파일의 속성을 얻으려 하면 일부 속성은 기본값(예: 크기 0) 을 반환할 수 있지만, 읽기 스트림을 열려고 하면 예외가 발생합니다.

폴더도 마찬가지입니다: DirectoryInfo 를 생성한다고 해서 디스크에 실제 폴더가 있다는 보장은 없습니다. 폴더가 필요하다면 Create() 등을 호출하세요.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION