
지난번에 FileStream의 작동 원리를 바이트 배열을 통해 직접 체험해 봤습니다.
여기서 "Hello World"와 같은 간단한 문자열을 쓰기 위해 매번 인코딩하고
바이트 배열로 변환하는 과정이 조금 번거롭게 느껴지지 않으셨나요?
그 번거로움을 덜어줄 StreamWriter와 StreamReader를 소개합니다!
FileStream의 가장 큰 특징은 바이트(byte) 기반이라는 점입니다.
하지만 우리는 '바이트'가 아닌 '텍스트(문자열)'를 저장하고 읽고 싶어 합니다.
StreamReader와 StreamWriter는 우리를 대신해서 변환 과정을 자동으로 처리해 줍니다.
StreamWriter - 만년필
StreamWriter는 문자열 데이터를 스트림에 쉽게 쓸 수 있게 해줍니다.
FileStream이 단순히 '잉크(바이트)'만 주는 것이라면,StreamWriter는 여기에 '만년필'을 추가로 주는 것과 같습니다.StreamWriter가 잉크를 찍어 종이에 써주는 거죠.StreamReader - 암호 해독 전문가
StreamReader는 스트림에서 데이터를 읽어와 우리에게 편리한 문자열 형태로 제공합니다.
FileStream이 암호문 같은 '바이트 덩어리'를 그대로 던져주는 것이라면,StreamReader는 우리가 읽을 수 있는 이야기로 '해독'해 주는 것과 같습니다.StreamWriter를 사용하면 Encoding.UTF8.GetBytes()같은 코드 대신,
WriteLine()이나 Write() 메서드로 문자열을 바로 파일에 쓸 수 있습니다.
[코드]
using System;
using System.IO;
using System.Text; // 문자 인코딩을 위해 필요합니다.
string filePath = @"C:\Temp\MyLog.log";
Directory.CreateDirectory(@"C:\Temp");
try
{
// StreamWriter를 생성할 때 파일 경로를 바로 지정할 수 있습니다.
// 두 번째 인자(append)를 true로 주면 파일 끝에 내용을 이어 씁니다.
using (StreamWriter sw = new StreamWriter(filePath, append: true, Encoding.UTF8))
{
sw.WriteLine("--- 로그 시작 ---");
sw.WriteLine($"시간: {DateTime.Now}");
sw.Write("상태: ");
sw.WriteLine("정상");
sw.WriteLine("--- 로그 종료 ---");
}
Console.WriteLine("로그 기록 완료!");
}
catch (Exception ex)
{
Console.WriteLine($"오류 발생: {ex.Message}");
}
new StreamWriter(경로, append, 인코딩, bufferSize, leaveOpen)append: true: 파일이 있으면 내용을 덧붙입니다.append: false: 파일이 있으면 덮어씁니다. (기본값)bufferSize: 내부 버퍼의 크기를 바이트 단위로 지정합니다. (기본값: 1024)leaveOpen true: StreamWriter가 닫혀도 스트림은 유지됩니다.leaveOpen false: StreamWriter가 닫히면 스트림도 닫힙니다. (기본값)sw.WriteLine(): 문자열을 쓰고 마지막에 줄바꿈 문자(\n)를 추가합니다.sw.Write(): 문자열을 쓰기만 하고 줄바꿈은 하지 않습니다.StreamReader는 파일의 내용을 한 줄씩 또는 전체를 쉽게 읽어올 수 있게 해줍니다.
[코드]
// 위에서 만든 파일을 읽어봅시다.
if (File.Exists(filePath))
{
try
{
using (StreamReader sr = new StreamReader(filePath, Encoding.UTF8))
{
Console.WriteLine("--- 파일 내용 전체 읽기 ---");
string allText = sr.ReadToEnd(); // 파일을 처음부터 끝까지 한 번에 읽음
Console.WriteLine(allText);
// 파일을 다시 읽으려면 스트림 위치를 처음으로 되돌려야 하지만,
// 여기서는 간단히 새 StreamReader를 만드는 예시를 보여드립니다.
}
using (StreamReader sr = new StreamReader(filePath, Encoding.UTF8))
{
Console.WriteLine("\n--- 파일 내용 한 줄씩 읽기 ---");
string line;
// ReadLine()은 한 줄을 읽고, 파일의 끝에 도달하면 null을 반환합니다.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine($"읽은 한 줄: {line}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"오류 발생: {ex.Message}");
}
}
new StreamReader(경로, 인코딩, BOM 감지, bufferSize, leaveOpen)BOM 감지: BOM 기반으로 인코딩을 자동 감지합니다. (기본값: true)bufferSize: 내부 버퍼의 크기를 바이트 단위로 지정합니다. (기본값: 1024)leaveOpen true: StreamReader가 닫혀도 스트림은 유지됩니다.leaveOpen false: StreamReader가 닫히면 스트림도 닫힙니다. (기본값)sr.ReadToEnd(): 파일의 모든 내용을 하나의 거대한 문자열로 읽어옵니다.sr.ReadLine(): 파일을 한 줄씩 읽어옵니다.[실행 결과]
로그 기록 완료!
--- 파일 내용 전체 읽기 ---
--- 로그 시작 ---
시간: 2025-09-03 오후 10:07:02
상태: 정상
--- 로그 종료 ---
--- 파일 내용 한 줄씩 읽기 ---
읽은 한 줄: --- 로그 시작 ---
읽은 한 줄: 시간: 2025-09-03 오후 10:07:02
읽은 한 줄: 상태: 정상
읽은 한 줄: --- 로그 종료 ---
실행 횟수에 따라 결과가 달라집니다.
이제 텍스트 파일을 다룰 때는 이 전문가들에게 맡겨보세요!
| 클래스 | 역할 | 주요 메서드 | 특징 |
|---|---|---|---|
StreamWriter | 텍스트 쓰기 전문가 | WriteLine(), Write() | 문자열 ⮕ 바이트 변환을 자동으로 처리 |
StreamReader | 텍스트 읽기 전문가 | ReadToEnd(), ReadLine() | 바이트 ⮕ 문자열 변환을 자동으로 처리 |