C#의 주요 파일 작업
C#은 프로그램이 외부 파일과 상호작용할 수 있도록 다양한 파일 작업 기능을 제공합니다. 대표적인 파일 작업은 다음과 같습니다.
- 파일 생성, 열기, 읽기 및 쓰기
- 기존 파일에 내용 추가(Append)
- 파일 삭제 등
FileStream 클래스란?
System.IO 네임스페이스에 포함된 FileStream 클래스는 파일을 읽고, 쓰고, 닫는 작업을 수행하는 핵심 클래스입니다. 이 클래스는 추상 클래스인 Stream을 상속받아 구현됩니다.
새 파일을 생성하거나 기존 파일을 열려면 먼저 FileStream 객체를 만들어야 합니다. FileStream 객체를 생성하는 기본 구문은 다음과 같습니다.
FileStream = new FileStream( <file_name>, <FileMode Enumerator>, <FileAccess Enumerator>, <FileShare Enumerator>);
여기서 사용되는 각 열거형 매개변수가 파일 작업 방식을 결정합니다. 아래에서 하나씩 살펴보겠습니다.
FileMode 열거형
FileMode 열거형은 파일을 여는 다양한 방식을 정의합니다. 주요 멤버는 다음과 같습니다.
- Append — 기존 파일을 열어 커서를 파일 끝으로 이동시키며, 파일이 존재하지 않으면 새로 생성합니다.
- Create — 새 파일을 생성합니다.
- CreateNew — 운영체제에 새 파일을 생성하도록 지정합니다.
- Open — 기존 파일을 엽니다.
- OpenOrCreate — 파일이 존재하면 해당 파일을 열고, 존재하지 않으면 새 파일을 생성하도록 운영체제에 지정합니다.
- Truncate — 기존 파일을 열어 파일 크기를 0바이트로 초기화합니다.
FileAccess 열거형
FileAccess 열거형은 파일에 대한 접근 권한을 정의하며, 다음 세 가지 멤버를 가집니다.
- Read(읽기 전용)
- ReadWrite(읽기 및 쓰기)
- Write(쓰기 전용)
FileShare 열거형
FileShare 열거형은 여러 프로세스가 동시에 같은 파일에 접근할 때의 공유 방식을 정의합니다.
- Inheritable — 자식 프로세스가 파일 핸들을 상속받을 수 있도록 허용합니다.
- None — 현재 파일의 공유를 거부합니다.
- Read — 파일을 읽기 목적으로 여는 것을 허용합니다.
- ReadWrite — 파일을 읽고 쓰기 위해 여는 것을 허용합니다.
- Write — 파일을 쓰기 목적으로 여는 것을 허용합니다.
예제: 파일 생성, 열기, 읽기
다음 예제는 FileStream을 사용하여 파일을 생성하고, 데이터를 쓴 뒤 다시 읽어오는 전 과정을 보여줍니다.
using System;
using System.IO;
namespace FileIOApplication {
class Program {
static void Main(string[] args) {
FileStream F = new FileStream("test.dat", FileMode.OpenOrCreate,
FileAccess.ReadWrite);
for (int i = 1; i <= 20; i++) {
F.WriteByte((byte)i);
}
F.Position = 0;
for (int i = 0; i <= 20; i++) {
Console.Write(F.ReadByte() + " ");
}
F.Close();
Console.ReadKey();
}
}
}
출력 결과
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1
출력 결과 분석
위 예제에서는 1부터 20까지의 값을 파일에 기록한 후, 파일 위치(Position)를 처음으로 되돌려 데이터를 다시 읽습니다. 출력 마지막에 -1이 표시되는 이유는 두 번째 반복문이 총 21번(0~20) 실행되지만 실제 파일에는 20바이트만 기록되어 있기 때문입니다. 스트림의 끝에 도달하면 ReadByte() 메서드는 더 이상 읽을 데이터가 없음을 의미하는 -1을 반환합니다.
실무에서는 파일 작업이 끝난 후 반드시 Close()를 호출하거나 using 문을 활용해 리소스를 해제하는 것이 좋습니다. 이를 통해 파일 잠금이나 리소스 누수와 같은 문제를 예방할 수 있습니다.