파일 입출력은 데이터의 저장과 관리를 위한 핵심 기술이며, C#에서는 다양한 클래스와 메서드를 통해 이를 쉽게 구현할 수 있습니다. 이 글에서는 파일 읽기와 쓰기, 그리고 StreamReader와 StreamWriter의 사용법을 설명하고, 심화된 내용으로 스트림의 원리와 활용을 소개합니다.
1. 파일 읽기와 쓰기
C#의 File 클래스는 파일 입출력을 간단히 처리할 수 있는 정적 메서드를 제공합니다.
파일 쓰기
File.WriteAllText: 문자열 데이터를 파일에 저장합니다.
using System;
using System.IO; // File 클래스 사용을 위해 필요
class Program
{
static void Main()
{
string filePath = "example.txt"; // 저장할 파일 경로
string content = "C# 파일 입출력 예제입니다."; // 저장할 내용
// 파일 쓰기
File.WriteAllText(filePath, content);
Console.WriteLine($"파일에 내용을 저장했습니다: {filePath}");
}
}
파일 읽기
File.ReadAllText: 파일의 내용을 문자열로 읽어옵니다.
class Program
{
static void Main()
{
string filePath = "example.txt";
// 파일 읽기
if (File.Exists(filePath)) // 파일이 존재하는지 확인
{
string content = File.ReadAllText(filePath);
Console.WriteLine($"파일 내용: {content}");
}
else
{
Console.WriteLine("파일이 존재하지 않습니다.");
}
}
}
💡 File.Exists를 사용해 파일의 존재 여부를 확인한 후 작업을 진행하는 것이 안전합니다.
줄 단위로 데이터 처리
- File.AppendAllText: 파일 끝에 데이터를 추가합니다.
- File.ReadAllLines: 파일의 각 줄을 문자열 배열로 읽어옵니다.
string filePath = "example.txt";
// 파일에 줄 추가
File.AppendAllText(filePath, "\n새로운 줄 추가");
// 파일에서 줄 단위로 읽기
string[] lines = File.ReadAllLines(filePath);
Console.WriteLine("파일 내용:");
foreach (string line in lines)
{
Console.WriteLine(line);
}
2. 스트림과 StreamReader/StreamWriter 사용법
**스트림(Stream)**은 파일, 네트워크, 메모리 등 다양한 데이터 소스와 상호작용하는 방식입니다. 데이터를 연속적인 흐름으로 처리하며, 파일을 다룰 때 효율적이고 유연한 방법을 제공합니다.
StreamWriter로 파일 쓰기
StreamWriter는 텍스트 데이터를 파일에 기록할 때 사용됩니다.
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "streamExample.txt";
// StreamWriter를 사용해 파일 쓰기
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.WriteLine("StreamWriter로 작성한 첫 번째 줄");
writer.WriteLine("StreamWriter로 작성한 두 번째 줄");
}
Console.WriteLine($"파일이 작성되었습니다: {filePath}");
}
}
💡 using 블록은 스트림을 자동으로 닫아주며, 리소스를 안전하게 관리합니다.
StreamReader로 파일 읽기
StreamReader는 텍스트 데이터를 파일에서 읽어올 때 사용됩니다.
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "streamExample.txt";
// StreamReader를 사용해 파일 읽기
if (File.Exists(filePath))
{
using (StreamReader reader = new StreamReader(filePath))
{
string line;
while ((line = reader.ReadLine()) != null) // 한 줄씩 읽기
{
Console.WriteLine(line);
}
}
}
else
{
Console.WriteLine("파일이 존재하지 않습니다.");
}
}
}
💡 ReadLine은 한 번에 한 줄씩 데이터를 읽어오는 메서드로, 메모리 사용량을 효율적으로 관리할 수 있습니다.
스트림의 원리와 활용
스트림의 동작 원리
- 입력 스트림(Input Stream): 데이터를 읽어오는 스트림 (예: StreamReader)
- 출력 스트림(Output Stream): 데이터를 기록하는 스트림 (예: StreamWriter)
버퍼(Buffer)와 성능
스트림은 데이터를 버퍼에 저장한 후 처리하므로, 대량의 데이터를 처리할 때 성능이 향상됩니다. 그러나 버퍼가 꽉 찬 상태에서 스트림을 닫지 않으면 데이터가 유실될 수 있으므로, 항상 스트림을 닫거나 using 블록을 사용하는 것이 중요합니다.
바이너리 데이터 처리
텍스트가 아닌 바이너리 데이터를 처리하려면 **FileStream**이나 **BinaryReader/BinaryWriter**를 사용할 수 있습니다.
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = "binaryExample.bin";
// 바이너리 데이터 쓰기
using (FileStream fs = new FileStream(filePath, FileMode.Create))
using (BinaryWriter writer = new BinaryWriter(fs))
{
writer.Write(123); // 정수
writer.Write(45.67); // 실수
writer.Write("바이너리 데이터"); // 문자열
}
Console.WriteLine("바이너리 데이터가 작성되었습니다.");
// 바이너리 데이터 읽기
using (FileStream fs = new FileStream(filePath, FileMode.Open))
using (BinaryReader reader = new BinaryReader(fs))
{
int intValue = reader.ReadInt32();
double doubleValue = reader.ReadDouble();
string stringValue = reader.ReadString();
Console.WriteLine($"읽은 데이터: {intValue}, {doubleValue}, {stringValue}");
}
}
}
💡 바이너리 데이터는 텍스트가 아닌 파일 형식(예: 이미지, 비디오, 실행 파일 등)을 다룰 때 유용합니다.