Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 스트림과 바이트 스트림 완벽 이해하기

C# 스트림(Stream)이란?

파일(File)은 특정 이름과 디렉터리 경로를 가지며 디스크에 저장된 데이터의 집합입니다. 이러한 파일을 읽기 또는 쓰기 위해 열게 되면, 프로그램과 파일 사이의 데이터 흐름인 스트림(Stream)이 생성됩니다.

스트림의 종류

  • 바이트 스트림(Byte Streams): Stream, FileStream, MemoryStream, BufferedStream 등이 포함됩니다.
  • 문자 스트림(Character Streams): TextReader-TextWriter, StreamReader, StreamWriter 및 기타 문자 기반 스트림이 포함됩니다.

바이트 스트림은 스트림 내부의 데이터를 바이트(byte) 단위로 처리하는 클래스들로 구성됩니다. 텍스트뿐 아니라 이미지, 동영상 같은 이진(binary) 데이터를 다룰 때 적합합니다.

Stream 클래스의 주요 속성

System.IO.Stream 추상 클래스는 모든 바이트 스트림 클래스의 기반이 됩니다. 대표적인 속성은 다음과 같습니다.

  • CanRead — 현재 스트림이 읽기를 지원하는지 여부
  • CanWrite — 현재 스트림이 쓰기를 지원하는지 여부
  • Length — 스트림의 전체 길이(바이트 수)

System.IO 네임스페이스

System.IO 네임스페이스에는 파일 생성·삭제, 파일 읽기·쓰기, 파일 닫기 등 다양한 파일 입출력 작업을 수행하는 여러 클래스들이 포함되어 있습니다.

앞서 살펴본 스트림 관련 입출력(I/O) 클래스들을 아래 표로 정리했습니다.

번호I/O 클래스 및 설명
1BinaryReader
이진 스트림에서 기본(primitive) 데이터 형식을 읽습니다.
2BinaryWriter
기본 데이터 형식을 이진 형식으로 씁니다.
3BufferedStream
바이트 스트림을 위한 임시 저장소(버퍼) 역할을 합니다.
4Directory
디렉터리 구조를 조작하는 정적 메서드를 제공합니다.
5DirectoryInfo
디렉터리에 대한 다양한 작업을 수행하는 인스턴스 클래스입니다.
6DriveInfo
드라이브에 대한 정보를 제공합니다.
7File
파일 조작을 위한 정적 메서드를 제공합니다.
8FileInfo
파일에 대한 다양한 작업을 수행하는 인스턴스 클래스입니다.
9FileStream
파일 내 임의 위치에서 읽고 쓰는 데 사용됩니다.
10MemoryStream
메모리에 저장된 스트림 데이터에 임의 접근(random access)할 때 사용됩니다.
11Path
파일 경로 정보에 대한 작업을 수행합니다.
12StreamReader
바이트 스트림에서 문자를 읽어 들이는 데 사용됩니다.
13StreamWriter
스트림에 문자를 쓰는 데 사용됩니다.
14StringReader
문자열 버퍼에서 데이터를 읽는 데 사용됩니다.
15StringWriter
문자열 버퍼에 데이터를 쓰는 데 사용됩니다.

FileStream 활용 예제

다음은 FileStream을 사용해 파일에 바이트를 쓰고 다시 읽어 오는 간단한 예제입니다.

using System;
using System.IO;
using System.Text;

class Program
{
static void Main()
{
string path = "sample.bin";

// 파일에 바이트 쓰기
byte[] data = Encoding.UTF8.GetBytes("Hello, C#");
using (FileStream fs = new FileStream(path, FileMode.Create))
{
fs.Write(data, 0, data.Length);
}

// 파일에서 바이트 읽기
using (FileStream fs = new FileStream(path, FileMode.Open))
{
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
Console.WriteLine(Encoding.UTF8.GetString(buffer)); // "Hello, C#" 출력
}
}
}

위 예제처럼 스트림 객체는 반드시 using 문 또는 Dispose() 호출을 통해 사용 후 해제해야 리소스 누수를 방지할 수 있습니다. 또한 BufferedStream을 함께 사용하면 작은 단위의 입출력을 버퍼에 모았다가 한 번에 처리하여 성능을 크게 향상시킬 수 있습니다.