본문 바로가기
카테고리 없음

C#에서 텍스트 파일 스트림 처리 예외 처리

by 디디이 2025. 7. 5.

C#의 파일 입출력 기능

C#에서 파일 입출력은 텍스트 파일을 생성하거나 읽는 기본적인 기능부터, 바이너리 파일 처리, 로그 저장, 설정 파일 관리 등 다양한 실무 작업에 활용됩니다. .NET Framework와 .NET Core/.NET 6 이후 환경 모두에서 공통적으로 사용되는 입출력 API들이 존재하며, 그 중 가장 많이 활용되는 것이 `System.IO` 네임스페이스입니다. 이 글에서는 C#의 대표적인 파일 입출력 방식과 주요 클래스, 실전 예제까지 단계별로 소개합니다.

1. 텍스트 파일 읽기 및 쓰기

텍스트 파일은 가장 기본적인 입출력 대상입니다. C#에서는 `File`, `FileInfo`, `StreamReader`, `StreamWriter` 등을 통해 손쉽게 파일을 읽고 쓸 수 있습니다. 예를 들어, 문자열을 간단히 파일에 저장하려면 다음과 같은 코드를 사용할 수 있습니다:

string path = "example.txt";
string content = "Hello, world!";
File.WriteAllText(path, content);

반대로 파일에서 텍스트를 읽을 때는 `File.ReadAllText()`를 사용합니다:

string result = File.ReadAllText(path);
Console.WriteLine(result);

여러 줄을 저장하거나 읽을 때는 `File.WriteAllLines()`나 `File.ReadAllLines()`를 사용하면 배열 형태로 각 줄을 처리할 수 있습니다. 또한 `StreamWriter`를 사용하면 줄 단위로 유연하게 기록할 수 있고, 파일이 존재하지 않을 경우 자동 생성되며, 존재할 경우 이어쓰기(append) 여부도 설정할 수 있습니다:

using (StreamWriter writer = new StreamWriter(path, append: true))
{
    writer.WriteLine("추가된 내용입니다.");
}

텍스트 파일 입출력은 로깅, 설정 저장, 데이터 임시 저장 등에 널리 활용되며, 간단한 문서 처리에도 응용할 수 있습니다.

2. 바이너리 파일 및 스트림 처리

텍스트 외에도 이미지, 오디오, 문서 파일 등 바이너리 데이터의 읽기/쓰기도 중요합니다. 이때는 `FileStream`, `BinaryReader`, `BinaryWriter`를 사용해 처리합니다. 예를 들어 파일 복사를 위해 바이너리 데이터를 읽고 쓰는 코드는 다음과 같습니다:

string sourcePath = "input.png";
string targetPath = "output.png";

using (FileStream source = new FileStream(sourcePath, FileMode.Open))
using (FileStream target = new FileStream(targetPath, FileMode.Create))
{
    source.CopyTo(target);
}

또는 데이터를 직접 바이트 배열로 읽어들일 수 있습니다:

byte[] buffer = File.ReadAllBytes(sourcePath);
File.WriteAllBytes("copy.png", buffer);

이러한 방식은 데이터 백업, 파일 암호화, 전송 전 처리, 업로드/다운로드 기능 구현 시 사용됩니다. 특히 이미지, PDF, Word 등 구조화된 파일을 다룰 때 반드시 필요한 기법입니다.

추가로, 메모리 기반 스트림인 `MemoryStream`을 사용하면 파일을 직접 저장하지 않고 메모리 내에서 데이터를 처리할 수 있어 테스트나 임시 처리 작업에 유용합니다. 그리고 파일 크기가 클 경우 `FileStream`의 버퍼 크기 조정이나 비동기 스트림(`FileStream.ReadAsync`)을 활용해 성능을 최적화할 수 있습니다.

3. 실전 팁 및 예외 처리 전략

파일 입출력 작업은 다양한 상황에서 예외가 발생할 수 있으므로 철저한 예외 처리가 필요합니다. 대표적인 예외로는 `FileNotFoundException`, `UnauthorizedAccessException`, `IOException` 등이 있습니다. 예를 들어 파일이 존재하지 않는 경우를 대비한 처리 방식은 다음과 같습니다:

try
{
    string data = File.ReadAllText("config.txt");
    Console.WriteLine(data);
}
catch (FileNotFoundException)
{
    Console.WriteLine("파일이 존재하지 않습니다.");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("파일 접근 권한이 없습니다.");
}
catch (Exception ex)
{
    Console.WriteLine($"오류 발생: {ex.Message}");
}

또한 경로가 잘못되었거나 디렉터리가 없는 경우를 대비해, 파일을 쓰기 전에 디렉터리를 자동 생성하는 것도 좋은 습관입니다:

string folderPath = "logs";
if (!Directory.Exists(folderPath))
    Directory.CreateDirectory(folderPath);

이 외에도 다음과 같은 실전 팁을 기억해두면 좋습니다:

  • 경로 구분은 Path.Combine()으로 OS 호환성 확보
  • 임시 파일은 Path.GetTempFileName()으로 생성
  • 반복 기록은 File.AppendAllText() 사용
  • 동시 접근 방지 위해 FileShare.None 설정

이러한 전략들은 파일 처리의 신뢰성과 안정성을 높이는 데 크게 기여하며, 특히 로그 파일, 사용자 설정, 보고서 저장 등에서 필수적으로 고려됩니다.

C#에서 파일 입출력은 `System.IO`의 다양한 클래스를 통해 직관적이고 유연하게 구현할 수 있습니다. 텍스트와 바이너리 데이터를 다루는 기본기부터, 예외 처리와 실전 적용 팁까지 잘 숙지해두면 다양한 실무 프로젝트에서 빠르고 안정적으로 데이터를 다룰 수 있습니다.