C# 파일 입출력(File I/O) 정리

공재원
∙∙조회 9

C# 파일 입출력(File I/O) 정리

1. 파일 입출력의 기본 개념

파일 입출력(File I/O)이란?

파일 입출력은 프로그램에서 파일을 읽거나 쓰는 작업을 의미한다.

게임 개발에서는 게임을 종료해도 데이터가 유지되어야 하는 경우가 많다. 예를 들어 플레이어의 레벨, 보유 아이템, 게임 진행 상황 등을 저장하고 다음 실행 때 다시 불러와야 한다.

파일 입출력은 이러한 데이터를 외부 파일에 저장하고 읽어오는 데 사용한다.

게임 개발에서 파일 입출력이 사용되는 상황

  • 게임 데이터 저장 및 불러오기: 플레이어 진행 상황, 세이브 데이터
  • 설정 파일 관리: 해상도, 볼륨, 키 설정
  • 외부 데이터 읽기: CSV, JSON, 로컬라이제이션 데이터
  • 로그 기록: 게임 실행 중 발생한 오류나 디버깅 정보

Stream(스트림)이란?

C#의 파일 입출력은 Stream이라는 구조를 기반으로 동작한다.

Stream은 데이터가 순차적으로 흐르는 통로라고 이해하면 된다.

프로그램이 데이터를 저장할 때는 Stream을 통해 데이터를 내보내고, 데이터를 읽을 때는 Stream을 통해 데이터를 가져온다.

Stream은 실제 데이터가 저장되는 장소가 파일인지, 메모리인지, 네트워크인지에 관계없이 공통된 방식으로 데이터를 처리할 수 있도록 한다.

Stream의 주요 특징

  • 데이터를 순차적으로 읽고 쓴다.
  • 내부 저장 방식에 관계없이 공통 메서드로 데이터를 처리한다.
  • Read, Write, Seek 등의 메서드를 제공한다.
  • 바이트 또는 바이트 배열 단위로 데이터를 처리한다.

Stream의 종류

분류설명대표 클래스
Backing Store Stream실제 저장소와 연결되는 스트림FileStream, MemoryStream
Stream Adapter기존 스트림을 감싸서 데이터를 다른 형태로 처리하는 클래스StreamReader, StreamWriter, BinaryReader, BinaryWriter

Backing Store Stream은 실제 데이터가 오가는 저장소와 연결되는 역할을 한다.

Stream Adapter는 기존 스트림을 감싸서 문자열이나 기본 데이터 타입처럼 사용하기 편한 형태로 변환하는 역할을 한다.

System.IO 네임스페이스

파일 입출력에 필요한 클래스는 System.IO 네임스페이스에 포함되어 있다.

파일 입출력을 사용하려면 System.IO를 참조해야 한다.

클래스역할
File파일 생성, 삭제, 읽기, 쓰기
Directory폴더 생성, 삭제, 목록 조회
Path파일 경로 문자열 처리
FileStream바이트 단위 파일 입출력
StreamReader텍스트 파일 읽기
StreamWriter텍스트 파일 쓰기
BinaryReader이진 데이터 읽기
BinaryWriter이진 데이터 쓰기

2. Unity에서의 파일 경로

Unity에서 제공하는 주요 경로

Unity는 실행 플랫폼에 따라 사용할 수 있는 파일 경로를 제공한다.

파일을 저장할 때는 데이터를 어떤 목적으로 사용하는지에 따라 적절한 경로를 선택해야 한다.

경로용도쓰기 가능 여부
Application.persistentDataPath세이브 데이터, 사용자 설정 저장가능
Application.dataPath프로젝트 Assets 폴더 경로빌드 후 쓰기 불가능
Application.streamingAssetsPath빌드에 포함할 읽기 전용 파일읽기 전용

Application.persistentDataPath

사용자가 생성한 데이터를 저장하기 위한 경로이다.

게임을 종료하거나 다시 실행해도 데이터가 유지되어야 하는 세이브 파일이나 설정 파일을 저장할 때 사용한다.

Application.dataPath

프로젝트의 Assets 폴더에 해당하는 경로이다.

에디터에서는 프로젝트의 Assets 폴더를 가리키지만, 빌드된 게임에서는 실행 파일의 데이터 폴더를 가리킨다.

빌드 후에는 일반적인 사용자 데이터 저장 경로로 사용할 수 없다.

Application.streamingAssetsPath

게임을 빌드할 때 함께 포함해야 하는 파일을 보관하는 경로이다.

외부에서 수정할 필요가 없는 설정 데이터나 기본 제공 파일 등을 넣는 용도로 사용한다.

핵심 구분

  • 게임 진행 상황을 저장하려면 persistentDataPath를 사용한다.
  • 프로젝트의 Assets 경로가 필요하면 dataPath를 사용한다.
  • 빌드에 포함할 읽기 전용 파일은 streamingAssetsPath를 사용한다.

Path.Combine으로 경로 조합하기

파일을 저장하려면 먼저 파일의 위치를 나타내는 경로가 필요하다.

경로를 문자열로 직접 연결하면 운영체제마다 다른 경로 구분자 때문에 문제가 발생할 수 있다.

이때 Path.Combine을 사용하면 운영체제에 맞는 경로 구분자를 사용하여 경로를 조합할 수 있다.

예를 들어 persistentDataPath 아래에 Save 폴더를 만들고, 그 안에 data.txt 파일을 저장하려면 다음과 같이 경로를 조합한다.

Path.Combine(Application.persistentDataPath, "Save", "data.txt")

기억할 점

Path.Combine은 경로를 안전하게 조합하기 위한 메서드이다.

경로를 문자열로 직접 연결하는 것보다 Path.Combine을 사용하는 것이 좋다.


3. 파일과 디렉터리 관리

Directory 클래스

Directory 클래스는 폴더를 관리하는 정적 메서드를 제공한다.

파일을 저장하기 전에 해당 폴더가 존재하는지 확인하거나, 폴더가 없다면 새로 생성하는 작업에 사용한다.

주요 메서드

메서드역할
Directory.Exists(path)폴더가 존재하는지 확인
Directory.CreateDirectory(path)폴더 생성
Directory.Delete(path)폴더 삭제
Directory.GetFiles(path)폴더 안의 파일 목록 반환
Directory.GetDirectories(path)하위 폴더 목록 반환

사용 흐름

  1. 저장할 폴더의 경로를 만든다.
  2. Directory.Exists로 폴더가 존재하는지 확인한다.
  3. 폴더가 없다면 Directory.CreateDirectory로 생성한다.
  4. Directory.GetFiles로 폴더 안의 파일 목록을 가져올 수 있다.

폴더가 존재하는지 확인하지 않고 파일을 저장하려고 하면 경로 문제로 오류가 발생할 수 있으므로, 저장 전에 폴더를 확인하는 습관이 중요하다.

Path 클래스

Path 클래스는 파일 경로 문자열을 다루는 기능을 제공한다.

파일 자체를 생성하거나 삭제하는 클래스가 아니라, 파일의 경로와 이름 등을 처리하는 유틸리티 클래스이다.

주요 메서드

메서드역할예시 결과
Path.Combine()경로 조합Save/data.txt
Path.GetFileName()파일명 추출data.txt
Path.GetFileNameWithoutExtension()확장자를 제외한 파일명 추출data
Path.GetExtension()확장자 추출.txt
Path.GetDirectoryName()디렉터리 경로 추출Save

예를 들어 player.json이라는 파일 경로가 있다면 Path 클래스를 사용하여 파일명, 확장자, 디렉터리 경로를 각각 가져올 수 있다.

Directory와 Path의 차이

  • Directory는 폴더를 생성하거나 삭제하고 목록을 조회한다.
  • Path는 파일 경로 문자열을 조합하거나 분석한다.

File 클래스

File 클래스는 파일을 관리하는 정적 메서드를 제공한다.

파일이 존재하는지 확인하거나, 파일을 삭제하고 복사하거나 이동할 때 사용한다.

주요 메서드

메서드역할
File.Exists(path)파일 존재 여부 확인
File.Delete(path)파일 삭제
File.Copy(src, dst)파일 복사
File.Move(src, dst)파일 이동

Directory와 File의 차이

Directory는 폴더를 관리하고 File은 파일을 관리한다.

둘 다 정적 메서드를 제공하므로 별도의 객체를 생성하지 않고 사용할 수 있다.


4. Stream 이해하기

Stream의 역할

Stream은 데이터의 순차적인 흐름을 추상화한 클래스이다.

파일이나 메모리, 네트워크처럼 서로 다른 저장소를 동일한 방식으로 다룰 수 있도록 한다.

Stream을 사용하면 실제 데이터가 어디에 저장되는지에 관계없이 Read와 Write 같은 공통 기능을 이용할 수 있다.

Stream의 주요 멤버

멤버역할
CanRead읽기가 가능한지 확인
CanWrite쓰기가 가능한지 확인
CanSeek위치 이동이 가능한지 확인
Length스트림 전체 길이 반환
Position현재 읽기 또는 쓰기 위치 반환
Read()바이트 배열로 데이터 읽기
Write()바이트 배열로 데이터 쓰기
ReadByte()1바이트 읽기
WriteByte()1바이트 쓰기
Seek()스트림 위치 이동
Close()스트림 닫기
Dispose()사용한 자원 해제

Length와 Position은 바이트 단위로 처리된다.

Read와 Write는 여러 바이트를 배열 형태로 처리할 수 있고, ReadByte와 WriteByte는 한 번에 1바이트를 처리한다.

FileStream

FileStream은 실제 파일과 연결되는 스트림이다.

파일을 바이트 단위로 읽거나 쓸 수 있으며, Stream의 기능을 사용하여 파일 데이터를 처리한다.

FileStream을 생성할 때는 FileMode를 지정하여 파일을 어떤 방식으로 열지 결정한다.

FileMode

FileMode는 파일을 열거나 생성할 때 적용할 방식을 결정하는 열거형이다.

FileMode역할
Create새 파일 생성. 기존 파일이 있으면 덮어씀
CreateNew새 파일 생성. 기존 파일이 있으면 예외 발생
Open기존 파일 열기. 파일이 없으면 예외 발생
OpenOrCreate파일이 있으면 열고, 없으면 생성
Append파일 끝에 데이터 추가. 파일이 없으면 생성
Truncate기존 파일을 열고 내용을 비움

FileMode에서 주의할 점

Create는 기존 파일의 내용을 지우고 새로 작성한다.

Open은 기존 파일이 반드시 존재해야 한다.

OpenOrCreate는 파일이 존재하면 기존 파일을 열고, 없으면 새로 만든다.

Append는 기존 파일의 끝에 데이터를 추가한다.

Truncate는 기존 파일의 내용을 비우는 방식이다.

File.OpenWrite와 File.Create의 차이

File.OpenWrite는 기존 파일을 열거나 파일이 없으면 생성하는 방식으로 동작한다.

기존 파일의 내용을 자동으로 지우지 않기 때문에 새로 작성하는 데이터가 기존 데이터보다 짧으면 뒤쪽에 이전 데이터가 남을 수 있다.

반면 File.Create는 새 파일을 생성하며, 기존 파일이 있다면 내용을 덮어쓴다.

따라서 기존 내용을 완전히 지우고 새로 저장하려면 File.Create 또는 FileMode.Create를 사용해야 한다.

바이트 읽기와 쓰기

FileStream은 데이터를 바이트 단위로 처리한다.

문자열도 컴퓨터 내부에서는 바이트 형태로 저장되기 때문에, FileStream을 이용하면 파일의 실제 바이트 데이터를 직접 다룰 수 있다.

  • WriteByte(): 1바이트를 파일에 기록한다.
  • Write(): 바이트 배열을 파일에 기록한다.
  • ReadByte(): 1바이트를 읽는다.
  • Read(): 바이트 배열에 데이터를 읽어온다.

ReadByte는 읽을 데이터가 더 이상 없으면 -1을 반환한다.

반환 타입이 byte가 아닌 int인 이유는 실제 바이트 값과 파일의 끝을 나타내는 -1을 구분하기 위해서이다.

Position과 Seek

스트림은 현재 읽거나 쓰는 위치를 기억한다.

Position은 현재 위치를 확인하거나 직접 변경할 때 사용한다.

Seek는 기준 위치와 이동할 거리를 지정하여 스트림의 위치를 이동할 때 사용한다.

SeekOrigin

값기준 위치
SeekOrigin.Begin스트림의 시작 위치
SeekOrigin.Current현재 위치
SeekOrigin.End스트림의 끝 위치

예를 들어 Position을 0으로 설정하면 스트림의 가장 처음으로 이동한다.

Seek를 사용하면 현재 위치를 기준으로 이동하거나 파일의 끝을 기준으로 위치를 변경할 수 있다.

Flush, Close, Dispose

스트림을 사용한 후에는 반드시 자원을 정리해야 한다.

스트림은 파일 핸들과 같은 운영체제 자원을 사용하기 때문에 사용이 끝나면 해제해야 한다.

Flush

스트림은 성능을 높이기 위해 데이터를 내부 버퍼에 모아두었다가 한 번에 기록할 수 있다.

Flush는 버퍼에 남아 있는 데이터를 실제 저장소에 기록하는 기능이다.

Close

스트림을 닫는 기능이다.

Close가 호출되면 사용 중인 스트림을 더 이상 사용할 수 없다.

Dispose

객체가 사용한 자원을 해제하는 기능이다.

스트림과 같이 운영체제 자원을 사용하는 객체는 사용 후 Dispose를 호출하여 자원을 정리해야 한다.

using 문

스트림을 안전하게 정리하기 위해 using 문을 사용한다.

using 블록이 끝나면 자동으로 Dispose가 호출되므로 예외가 발생하더라도 자원을 정리할 수 있다.

스트림은 파일 핸들을 사용하기 때문에 직접 Close를 호출하는 것보다 using 문을 사용하는 것이 안전하다.

핵심 흐름

  1. 스트림을 생성한다.
  2. 데이터를 읽거나 쓴다.
  3. using 블록이 종료된다.
  4. Dispose가 자동으로 호출되어 자원이 정리된다.

5. 텍스트 파일 입출력

StreamWriter

StreamWriter는 스트림을 감싸서 문자열을 텍스트 파일에 쓰는 클래스이다.

FileStream이 바이트 단위로 데이터를 처리한다면, StreamWriter는 문자열을 편리하게 기록할 수 있도록 도와준다.

게임 로그나 설정 파일처럼 사람이 직접 읽을 수 있는 데이터를 저장할 때 사용한다.

주요 메서드

  • Write(): 데이터를 기록한다.
  • WriteLine(): 데이터를 기록하고 줄을 바꾼다.

StreamWriter는 숫자나 bool 같은 값도 문자열 형태로 변환하여 저장할 수 있다.

File.CreateText와 File.AppendText

StreamWriter를 생성하는 과정은 File 클래스의 메서드를 이용하여 간단하게 처리할 수 있다.

메서드역할
File.CreateText(path)텍스트 파일을 생성하거나 기존 파일을 덮어씀
File.AppendText(path)기존 파일의 마지막에 텍스트 추가

기존 파일의 내용을 새로 작성하려면 CreateText를 사용하고, 기존 내용은 유지하면서 새로운 내용을 추가하려면 AppendText를 사용한다.

StreamReader

StreamReader는 스트림을 감싸서 텍스트 파일의 문자열을 읽는 클래스이다.

StreamWriter가 텍스트 파일에 데이터를 쓰는 역할이라면 StreamReader는 파일에 저장된 데이터를 읽는 역할을 한다.

주요 메서드

메서드역할
ReadLine()한 줄 읽기
ReadToEnd()현재 위치부터 파일 끝까지 읽기
Read()문자 하나 읽기
Peek()다음 문자를 미리 확인

ReadLine은 파일의 끝에 도달하면 null을 반환한다.

따라서 null이 반환될 때까지 반복하면 파일의 모든 줄을 읽을 수 있다.

ReadToEnd는 현재 위치부터 파일의 끝까지 내용을 한 번에 읽는다.

Peek는 다음 문자를 확인하지만 실제 읽기 위치는 이동하지 않는다.

텍스트 데이터 변환

StreamWriter는 숫자나 bool도 문자열로 변환하여 저장한다.

예를 들어 정수 100을 저장하면 파일에는 문자열 "100"이 기록된다.

따라서 파일에서 데이터를 다시 읽어올 때는 원래 자료형으로 변환해야 한다.

대표적인 변환 메서드

메서드역할
int.Parse()문자열을 int로 변환
float.Parse()문자열을 float로 변환
bool.Parse()문자열을 bool로 변환

텍스트 파일은 사람이 직접 내용을 확인하기 쉽다는 장점이 있지만, 데이터를 읽을 때 다시 파싱하는 과정이 필요하다.

Culture(문화권)

숫자의 문자열 표현 방식은 실행 환경의 문화권 설정에 영향을 받는다.

예를 들어 소수점을 사용하는 방식은 국가나 지역에 따라 다를 수 있다.

일부 환경에서는 3.14를 "3,14"처럼 표현할 수 있다.

따라서 서로 다른 환경에서 동일한 파일을 저장하고 읽어야 한다면 문화권을 고정하는 것이 안전하다.

CultureInfo.InvariantCulture를 사용하면 실행 환경의 문화권에 영향을 받지 않는 일정한 형식으로 숫자를 처리할 수 있다.

인코딩(Encoding)

인코딩은 문자를 바이트 데이터로 변환하는 방식이다.

컴퓨터는 문자를 그대로 저장하는 것이 아니라 바이트 형태로 변환하여 저장한다.

StreamWriter와 StreamReader는 기본적으로 UTF-8 인코딩을 사용한다.

UTF-8은 한글을 포함한 유니코드 문자를 처리할 수 있다.

외부에서 가져온 파일의 글자가 깨져 보인다면 원본 파일과 읽을 때 사용하는 인코딩이 서로 다를 가능성이 있다.

이 경우 원본 파일의 인코딩에 맞춰 읽어야 한다.

다만 UTF-8 이외의 인코딩은 빌드 플랫폼이나 스크립팅 백엔드에 따라 지원되지 않을 수 있으므로, 가능하면 원본 파일을 UTF-8로 변환하여 사용하는 것이 안전하다.


6. 이진 파일 입출력

BinaryWriter와 BinaryReader

BinaryWriter와 BinaryReader는 기본 자료형을 이진 데이터 형태로 읽고 쓰는 클래스이다.

StreamWriter와 StreamReader가 데이터를 사람이 읽을 수 있는 문자열로 처리한다면, BinaryWriter와 BinaryReader는 데이터를 이진 형식으로 처리한다.

BinaryWriter

  • 기본 자료형을 이진 형식으로 파일에 기록한다.
  • 문자열, 정수, 실수, bool 등을 기록할 수 있다.

BinaryReader

  • 이진 형식으로 저장된 데이터를 읽는다.
  • 저장된 데이터의 자료형에 맞는 메서드를 사용해야 한다.

BinaryWriter와 BinaryReader 사용 시 주의점

BinaryWriter로 데이터를 저장한 순서와 BinaryReader로 데이터를 읽는 순서는 반드시 일치해야 한다.

예를 들어 이름, 레벨, 체력, 생존 여부 순서로 저장했다면 읽을 때도 같은 순서와 자료형으로 읽어야 한다.

순서나 자료형이 다르면 잘못된 데이터가 읽히거나 예외가 발생할 수 있다.

BinaryReader 주요 메서드

메서드읽는 자료형바이트 수
ReadBoolean()bool1
ReadByte()byte1
ReadChar()char가변
ReadInt32()int4
ReadInt64()long8
ReadSingle()float4
ReadDouble()double8
ReadString()string가변
ReadBytes(count)byte[]지정한 개수

자료형에 맞는 읽기 메서드를 선택해야 한다.

예를 들어 int를 저장했다면 ReadInt32로 읽고, float를 저장했다면 ReadSingle로 읽는다.

텍스트 파일과 이진 파일 비교

항목텍스트 방식이진 방식
대표 클래스StreamWriter / StreamReaderBinaryWriter / BinaryReader
파일 내용사람이 읽을 수 있음사람이 읽기 어려움
파일 크기상대적으로 큼상대적으로 작음
데이터 처리문자열 파싱 필요자료형에 맞게 직접 읽음
편집메모장 등으로 편집 가능전용 도구 필요
주요 용도설정, 로그, CSV, JSON세이브 데이터, 리소스

텍스트 방식은 파일 내용을 직접 확인할 수 있기 때문에 개발 중 디버깅에 편리하다.

이진 방식은 데이터를 효율적으로 저장할 수 있으며, 파일 크기가 상대적으로 작고 파싱 과정이 필요하지 않다는 장점이 있다.

따라서 어떤 방식이 더 좋은지는 데이터의 목적에 따라 결정해야 한다.


7. File 클래스의 단축 메서드

File 클래스 단축 메서드란?

File 클래스는 Stream을 직접 생성하고 관리하지 않아도 파일 입출력을 간단하게 처리할 수 있는 메서드를 제공한다.

내부적으로 스트림을 열고, 데이터를 처리하고, 닫는 과정을 자동으로 수행한다.

간단한 파일 입출력 작업이라면 File 클래스의 단축 메서드를 사용하는 것이 편리하다.

주요 메서드

메서드역할
File.WriteAllText(path, text)문자열 전체를 파일에 기록
File.ReadAllText(path)파일 전체를 문자열로 읽기
File.WriteAllLines(path, lines)문자열 배열을 줄 단위로 기록
File.ReadAllLines(path)파일을 줄 단위 문자열 배열로 읽기
File.WriteAllBytes(path, bytes)바이트 배열을 파일에 기록
File.ReadAllBytes(path)파일 전체를 바이트 배열로 읽기
File.AppendAllText(path, text)기존 파일 끝에 텍스트 추가

WriteAllText와 ReadAllText

WriteAllText는 문자열 전체를 파일에 기록한다.

ReadAllText는 파일에 저장된 전체 내용을 하나의 문자열로 읽어온다.

설정 파일이나 간단한 텍스트 데이터를 저장하고 불러올 때 사용할 수 있다.

WriteAllLines와 ReadAllLines

WriteAllLines는 문자열 배열의 각 요소를 줄 단위로 파일에 기록한다.

ReadAllLines는 파일의 각 줄을 문자열 배열의 요소로 가져온다.

여러 줄로 구성된 데이터를 처리할 때 편리하다.

상황에 따른 사용 방법

상황권장 방식
파일 전체를 한 번에 읽고 쓰기File.ReadAllText / File.WriteAllText
기존 파일 끝에 내용 추가File.AppendAllText
대용량 파일을 줄 단위로 처리StreamReader / StreamWriter
바이트 단위로 세밀하게 제어FileStream
구조화된 이진 데이터 처리BinaryReader / BinaryWriter

파일 전체를 간단하게 처리한다면 File 클래스의 단축 메서드를 사용한다.

파일을 순차적으로 읽거나 대용량 데이터를 처리해야 한다면 StreamReader와 StreamWriter를 사용한다.

바이트 단위로 직접 제어해야 한다면 FileStream을 사용한다.

구조화된 이진 데이터를 저장하고 불러와야 한다면 BinaryWriter와 BinaryReader를 사용한다.


8. 면접 대비 질문과 답변

Q1. 파일 입출력이란 무엇인가?

파일 입출력은 프로그램에서 파일을 읽고 쓰는 작업이다. 게임에서는 세이브 데이터, 사용자 설정, 로그 등을 저장하고 불러오는 데 사용한다.

Q2. Stream이란 무엇인가?

Stream은 데이터의 순차적인 흐름을 추상화한 클래스이다. 실제 저장소가 파일, 메모리, 네트워크인지에 관계없이 공통된 방식으로 데이터를 읽고 쓸 수 있도록 한다.

Q3. System.IO 네임스페이스는 어떤 역할을 하는가?

파일과 디렉터리 관리, 스트림을 이용한 파일 입출력 등에 필요한 클래스들을 제공한다.

Q4. Unity에서 게임 데이터를 저장할 때 어떤 경로를 사용하는가?

Application.persistentDataPath를 사용한다. 사용자 데이터가 저장되는 경로이므로 세이브 데이터나 설정 파일을 저장할 때 적합하다.

Q5. Path.Combine을 사용하는 이유는 무엇인가?

운영체제마다 경로 구분자가 다를 수 있기 때문이다. Path.Combine을 사용하면 플랫폼에 맞는 경로 구분자를 사용하여 안전하게 경로를 조합할 수 있다.

Q6. Directory와 File 클래스의 차이는 무엇인가?

Directory는 폴더를 생성하거나 삭제하고 목록을 조회하는 역할을 한다. File은 파일을 생성하거나 삭제하고 복사하거나 이동하는 역할을 한다.

Q7. FileStream은 어떤 역할을 하는가?

FileStream은 파일과 연결된 스트림으로, 바이트 단위로 파일 데이터를 읽고 쓰는 역할을 한다.

Q8. FileMode는 무엇인가?

FileMode는 FileStream을 생성할 때 파일을 어떤 방식으로 열거나 생성할지 결정하는 열거형이다.

Q9. Position과 Seek의 차이는 무엇인가?

Position은 현재 스트림 위치를 확인하거나 직접 변경하는 데 사용한다. Seek는 기준 위치와 이동할 거리를 지정하여 스트림 위치를 이동하는 데 사용한다.

Q10. using 문을 사용하는 이유는 무엇인가?

using 문은 블록이 종료될 때 Dispose를 자동으로 호출한다. 스트림이 사용한 파일 핸들과 같은 자원을 안전하게 해제할 수 있다.

Q11. Flush는 어떤 역할을 하는가?

내부 버퍼에 남아 있는 데이터를 실제 저장소에 기록하는 역할을 한다.

Q12. StreamWriter와 StreamReader의 차이는 무엇인가?

StreamWriter는 텍스트 파일에 문자열을 기록하고, StreamReader는 텍스트 파일에서 문자열을 읽는다.

Q13. ReadLine은 파일의 끝에 도달하면 무엇을 반환하는가?

null을 반환한다. 따라서 null인지 확인하면 파일의 끝에 도달했는지 판단할 수 있다.

Q14. 텍스트 파일과 이진 파일의 차이는 무엇인가?

텍스트 파일은 사람이 읽을 수 있는 문자열 형태로 데이터를 저장한다. 이진 파일은 데이터를 이진 형식으로 저장하므로 사람이 직접 읽기 어렵지만 파일 크기가 상대적으로 작고 파싱 과정이 필요하지 않다.

Q15. BinaryWriter와 BinaryReader를 사용할 때 주의할 점은 무엇인가?

데이터를 저장한 순서와 자료형에 맞춰 읽어야 한다. 저장 순서와 읽는 순서가 다르면 잘못된 데이터가 읽히거나 예외가 발생할 수 있다.

Q16. File.WriteAllText와 StreamWriter의 차이는 무엇인가?

File.WriteAllText는 파일 전체에 문자열을 간단하게 기록하는 단축 메서드이다. StreamWriter는 스트림을 직접 다루면서 문자열을 기록할 수 있어 여러 번에 걸쳐 데이터를 쓰거나 세밀하게 처리할 때 사용할 수 있다.

Q17. 인코딩이란 무엇인가?

인코딩은 문자를 바이트 데이터로 변환하는 방식이다. 파일을 저장하거나 읽을 때 사용하는 인코딩이 서로 다르면 문자가 깨져 보일 수 있다.


9. 면접 전 핵심 정리

  • 파일 입출력은 프로그램에서 파일을 읽고 쓰는 작업이다.
  • Stream은 데이터의 순차적인 흐름을 추상화한 클래스이다.
  • System.IO는 파일 입출력 관련 클래스를 제공하는 네임스페이스이다.
  • Application.persistentDataPath는 Unity에서 세이브 데이터와 사용자 설정을 저장하는 경로이다.
  • Path.Combine은 운영체제에 맞는 경로 구분자를 사용하여 경로를 조합한다.
  • Directory는 폴더를 관리하고 File은 파일을 관리한다.
  • Path는 파일 경로 문자열을 조작한다.
  • FileStream은 바이트 단위로 파일 데이터를 읽고 쓴다.
  • FileMode는 파일을 어떤 방식으로 열거나 생성할지 결정한다.
  • Position은 현재 위치를 확인하거나 변경하고, Seek는 기준 위치를 이용해 이동한다.
  • Flush는 버퍼에 남은 데이터를 저장소에 기록한다.
  • using 문은 Dispose를 자동으로 호출하여 자원을 안전하게 해제한다.
  • StreamWriter는 텍스트 파일에 문자열을 쓰고 StreamReader는 문자열을 읽는다.
  • BinaryWriter는 이진 데이터를 쓰고 BinaryReader는 이진 데이터를 읽는다.
  • 이진 데이터를 읽을 때는 저장한 순서와 자료형을 일치시켜야 한다.
  • File 클래스의 단축 메서드는 간단한 파일 입출력을 편리하게 처리한다.
  • 텍스트 방식은 사람이 읽고 편집하기 쉽고, 이진 방식은 상대적으로 파일 크기가 작다.

전체 흐름 이해하기

파일 입출력은 데이터를 저장하고 불러오는 작업이다. Unity에서는 저장할 위치를 결정하고 Path를 이용해 경로를 만든다. Directory와 File로 폴더와 파일을 관리하며, 실제 데이터는 Stream을 통해 읽고 쓴다.

문자열 형태의 데이터를 다룰 때는 StreamWriter와 StreamReader를 사용하고, 이진 형태의 데이터를 다룰 때는 BinaryWriter와 BinaryReader를 사용한다. 스트림을 직접 사용할 때는 using 문으로 자원을 안전하게 정리한다.