Abstract
이름 때문에 오해하기 쉽지만, 이 모듈은 File.ReadAllBytes 같은 일반 파일 유틸이 아닙니다. 여러 개의 작은 파일을 하나의 큰 파일 안에 넣어 관리하는 "가상 파일 시스템"입니다. zip 처럼 한 덩어리지만 압축을 풀지 않고도 안의 파일을 이름으로 바로 읽고 쓸 수 있습니다.
왜 이런 것이 필요한가
•
파일이 수천 개면 OS 수준에서 열고 닫는 비용과 디스크 낭비가 커진다. 하나로 묶으면 파일 핸들 하나로 끝난다
•
모바일에서 수천 개의 파일을 설치·복사하는 것보다 큰 파일 몇 개가 훨씬 빠르다
•
내용물이 낱개 파일로 노출되지 않는다
원작 GameFramework 는 AssetBundle 수천 개를 몇 개의 파일로 묶어 배포하려고 이 모듈을 만들었습니다.
기본 사용법
FileSystemComponent fileSystemComponent = GameEntry.GetComponent<FileSystemComponent>();
string path = System.IO.Path.Combine(Application.persistentDataPath, "replays.dat");
const int MaxFileCount = 256; // 담을 수 있는 최대 파일 수
const int MaxBlockCount = 1024; // 내부 블록 수 (파일 수의 몇 배로 잡는다)
// 처음이면 만들고, 있으면 연다
IFileSystem fs = System.IO.File.Exists(path)
? fileSystemComponent.LoadFileSystem(path, FileSystemAccess.ReadWrite)
: fileSystemComponent.CreateFileSystem(path, FileSystemAccess.ReadWrite, MaxFileCount, MaxBlockCount);
fs.WriteFile("stage01.rep", replayBytes); // 안에 파일 쓰기
byte[] data = fs.ReadFile("stage01.rep"); // 이름으로 읽기
bool exists = fs.HasFile("stage01.rep");
fs.DeleteFile("stage01.rep");
fileSystemComponent.DestroyFileSystem(fs, false); // 닫기 (false = 물리 파일은 남긴다)
C#
복사
세이브 데이터에는 무엇을 쓰나
저장할 것 | 맞는 도구 |
볼륨, 최고 점수 같은 키-값 몇 개 | Setting 모듈 |
세이브 파일 하나 (JSON 등) | System.IO.File 을 그대로 쓴다 |
수백~수천 개의 작은 파일 | 이 모듈 |
ToyboxNightmare 에서는
쓰지 않습니다. 또 이 에디션은 리소스 계층이 Addressables 라서, 원작에서 이 모듈의 주 고객이던 "번들 묶음 배포"도 일어나지 않습니다. 게임 코드가 직접 필요할 때만 쓰는 독립 유틸로 남아 있습니다.
본문을 읽을 때 주의할 점
•
아래 본문은 거의 전부 AndroidFileSystemStream 이야기입니다. 이것은 가상 파일 시스템이 APK 안(StreamingAssets)에 들어 있을 때 그 물리 파일을 읽기 위한 내부 부품이고, 게임 코드가 직접 new 해서 쓰는 클래스가 아닙니다. 게임 코드의 창구는 위의 FileSystemComponent 와 IFileSystem 입니다.
•
본문의 "플랫폼 독립적인 파일 읽기/쓰기 인터페이스"라는 설명은 절반만 맞습니다. 플랫폼 차이를 감춰 주는 것은 "묶음 파일을 어떻게 여느냐"까지이고, 일반 파일 접근을 추상화해 주지는 않습니다.
•
CreateFileSystem 의 최대 파일 수·블록 수는 만들 때 고정됩니다. 나중에 늘릴 수 없으니 넉넉하게 잡습니다.
•
Android 의 StreamingAssets 안에 둔 묶음은 읽기 전용입니다. 쓰려면 persistentDataPath 로 옮겨야 합니다.
File System (파일 시스템)
개요 (Overview)
파일 시스템 컴포넌트는 Unity 게임 프레임워크에서 플랫폼 독립적인 파일 접근 및 관리 인터페이스를 제공합니다.
이를 통해 게임은 플랫폼별 구현 세부 사항을 직접 다루지 않고도 파일 작업을 수행할 수 있으며, 배포 플랫폼과 관계없이 일관된 API를 제공합니다.
원격 소스에서 파일을 다운로드하는 방법은 Download System을 참조하세요.
시스템 개요 (System Overview)
파일 시스템은 다음 기능을 지원합니다:
•
플랫폼 독립적인 파일 읽기 및 쓰기
•
다양한 저장 위치에서 파일 접근
•
효율적인 I/O를 위한 파일 스트림 관리
•
플랫폼별 파일 접근 메서드 지원
아키텍처 (Architecture)
파일 시스템은 게임 프레임워크 전반에서 사용되는 컴포넌트-매니저-헬퍼 패턴을 따릅니다.
핵심 구성 요소 (Key Components)
FileSystemStream
FileSystemStream은 추상 기본 클래스로, 플랫폼 간 공통의 파일 작업 인터페이스를 제공합니다.
제공 기능:
•
파일 데이터 읽기
•
파일 데이터 쓰기
•
특정 위치로 시킹(Seek)
•
파일 라이프사이클 관리 (열기/닫기)
플랫폼별 구현체(AndroidFileSystemStream 등)는 이 클래스를 상속받아 실제 동작을 정의합니다.
AndroidFileSystemStream
AndroidFileSystemStream은 안드로이드 전용 구현체로, 안드로이드 애셋 시스템 내의 파일에 접근합니다.
특징:
•
읽기 전용: 읽기 작업만 지원
•
Asset Manager 연동: 안드로이드 AssetManager를 사용하여 파일 접근
•
특수 경로 형식 필요: !/assets/ 분할 플래그를 포함하는 경로 형식 사용
•
플랫폼 제약: 새 파일 생성 불가, 기존 파일 수정 불가
예:
// 안드로이드 전용 경로 형식
string path = "jar:file://your_apk_path!/assets/yourfile.dat";
using (AndroidFileSystemStream stream = new AndroidFileSystemStream(path, FileSystemAccess.Read, false))
{
// 파일 읽기 작업 수행
}
C#
복사
파일 시스템 사용법 (Using the File System)
안드로이드에서 파일 읽기 (Reading Files on Android)
파일 스트림 생성:
string path = "jar:file://your_apk_path!/assets/yourfile.dat";
using (AndroidFileSystemStream stream = new AndroidFileSystemStream(path, FileSystemAccess.Read, false))
{
// 파일 읽기
}
C#
복사
데이터 읽기:
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
// 읽은 데이터 처리
C#
복사
시킹 (Seeking):
// 특정 위치로 이동 (앞으로 가는 시킹만 효율적으로 지원)
stream.Seek(position, SeekOrigin.Begin);
C#
복사
제한 사항 (Limitations):
•
데이터 쓰기 불가 (WriteByte, Write는 예외 발생)
•
새 파일 생성 불가
•
파일 길이 수정 불가
파일 시스템 기능 및 제약 (Features and Limitations)
기능 | 설명 | 안드로이드 지원 |
파일 읽기 | 파일에서 바이너리 데이터 읽기 | ✓ 지원 |
파일 쓰기 | 파일에 데이터 쓰기 | ✗ 미지원 |
시킹 | 파일 내 특정 위치 탐색 | ✓ 제한적 지원 (앞으로만 효율적) |
길이 조회 | 파일 길이 확인 | ✓ 지원 |
파일 생성 | 새 파일 생성 | ✗ 미지원 |
디스크 플러시 | 변경 사항 저장소에 강제 반영 | ✗ 미지원 |
경로 형식 | 파일 경로에 필요한 형식 | !/assets/ 포함 필요 |
다른 프레임워크 시스템과의 통합 (Integration with Other Framework Systems)
파일 시스템은 다른 프레임워크 시스템의 기초 서비스로 동작하며, 다양한 I/O 작업에서 플랫폼에 독립적인 인터페이스를 제공합니다.
안드로이드 구현 세부사항 (Android Implementation Details)
Asset Manager 연동 (Asset Manager Integration)
AndroidFileSystemStream은 앱에 패키징된 파일에 접근하기 위해 안드로이드 Asset Manager를 사용합니다.
초기화:
•
현재 안드로이드 액티비티에서 AssetManager를 가져옴
•
효율적인 JNI 호출을 위한 Java 메서드 ID 준비
경로 처리:
•
!/assets/ 마커가 포함된 경로를 파싱하여 실제 자산 경로 추출
•
예:
jar:file:///data/app/package-1/base.apk!/assets/file.dat
→ file.dat
Plain Text
복사
리소스 관리:
•
Java 객체를 올바르게 Dispose하여 메모리 누수 방지
•
JNI 참조를 효율적으로 처리
결론 (Conclusion)
파일 시스템 컴포넌트는 게임 프레임워크에서 플랫폼 독립적인 파일 작업 인터페이스를 제공합니다.
이 문서는 주로 안드로이드 구현을 다루었지만, 전체 아키텍처는 FileSystemStream 인터페이스를 통해 다중 플랫폼 지원을 염두에 두고 설계되었습니다.
게임에서 파일 작업을 구현할 때는:
•
타겟 플랫폼에 맞는 FileSystemStream을 사용해야 하며
•
특히 모바일 환경에서는 파일 접근 권한 및 제약 사항을 반드시 고려해야 합니다.







