1. 들어가기
파일은 그냥 어떤 저장장치(하드디스크, SSD, USB, 심지어 플로피디스크까지! 할아버지께 안부 전해줘~)에 물리적으로 저장된 데이터 덩어리야. 사용자 입장에선 파일은 열고, 읽고, 수정하고, 저장할 수 있는 어떤 "것"이지.
프로그래밍에서 파일은 이름과 위치가 있는 바이트들의 연속이고, 너 같은 개발자한텐 이름, 경로(주소), 크기, 생성일 등등의 속성을 가진 객체야. 제일 중요한 건: 파일은 영속적(지속적) 데이터 저장소라는 거야. 프로그램이 실행되는 동안 메모리에서 일어난 건 보통 프로그램이 끝나면 다 사라지지만, 파일은 남아있지.
파일 시스템이 뭐야?
파일 시스템은 디스크에 파일을 저장하고 정리하는 방식이야. "어디에, 어떻게 파일을 찾지?", "누가 접근할 수 있지?", "폴더(디렉토리)는 어떻게 생겼지?", "파일 이름과 내용은 어떻게 찾지?" 같은 질문에 답해주는 거지.
엄청 큰 옷장이 있다고 생각해봐. 서랍이 여러 개 있고, 각 서랍엔 폴더가 있고, 폴더 안엔 문서(파일)가 있어. C# 필기노트를 찾으려면 옷장 열고, 서랍 찾고, 폴더 꺼내서 그 안에서 원하는 종이를 찾아야 해. 파일 시스템이 정보를 이렇게 정리해주는 거야.
유명한 파일 시스템들
- NTFS — Windows의 "기본" 파일 시스템.
- FAT32, exFAT — USB, SD카드, 외장 저장장치용.
- EXT4 — Linux에서 인기 많아.
- APFS, HFS+ — macOS용.
C# 개발자한텐 보통 별로 중요하지 않아. .NET이 구현 세부사항을 숨겨주고, 넌 그냥 "파일/폴더"라는 추상화로 작업하거든. 그래도 가끔 알아두면 좋아. 예를 들어, NTFS에선 파일 이름에 공백이나 특수문자 많이 쓸 수 있는데, FAT32에선 안 돼.
2. 디렉토리(폴더)는 어떻게 생겼을까
디렉토리(또는 폴더)는 다른 파일이나 디렉토리 목록을 담고 있는 특별한 파일 타입이야. 디렉토리 트리(파일 계층 구조)는 루트에서 파일까지 가는 익숙한 경로야. 예를 들면, C:\Users\이반\Documents\MyFile.txt 이런 식.
- 루트 — 디스크의 맨 처음 (C:\).
- 그 안에 폴더(서브폴더)가 있고, 그 안에 파일이나 또 다른 폴더가 있어.
간단하게 그림으로 보면:
C:\
└── Users\
└── 이반\
├── Documents\
│ └── MyFile.txt
└── Pictures\
└── Cat.jpg
3. 파일 경로(file path)란?
파일 경로는 디렉토리 트리에서 파일의 "주소"야. 이걸로 원하는 파일이나 폴더를 정확히 찾을 수 있어.
절대 경로와 상대 경로
- 절대 경로: 파일 시스템의 루트에서 시작해.
Windows: C:\Users\이반\Documents\MyFile.txt
Linux/macOS: /home/ivan/Documents/MyFile.txt - 상대 경로: 현재 위치(현재 디렉토리)에서 시작해.
예를 들어, 네 프로그램이 C:\Users\이반 폴더에서 실행됐다면, 상대 경로 Documents\MyFile.txt도 같은 파일을 가리켜.
현재 디렉토리는 특별한 개념이야. 모든 상대 경로의 "기준점"이지. 프로그램을 실행하면 보통 .exe 파일이 있는 폴더나, 콘솔을 연 폴더가 현재 디렉토리가 돼.
도식: 절대 경로와 상대 경로
절대 경로 상대 경로
C:\Projects\MyApp\logs\output.txt logs\output.txt
└─ 디스크 루트 (C:) └─ MyApp에서 실행 기준
경로 구분자: \ 와 /
Windows에선 역슬래시(\)를 쓰고, Linux/macOS에선 보통 슬래시(/)를 써.
요즘 .NET은 둘 다 지원하지만, 한 프로젝트에서 섞어 쓰지 않는 게 좋아. 경로 만들 땐 항상 전용 API(애플리케이션 프로그래밍 인터페이스)를 쓰고, 문자열을 직접 이어붙이지 마.
4. 프로그램이 파일을 어떻게 볼까
.NET에는 파일 작업을 위한 다양한 도구가 있어. 대표적인 것들:
- System.IO.File: 파일 빠르게 읽기, 쓰기, 삭제, 존재 여부 확인 등등을 위한 static 메서드.
- System.IO.Directory: 폴더 작업용 비슷한 메서드.
- System.IO.FileInfo 와 System.IO.DirectoryInfo: 파일/폴더 메타데이터에 접근할 수 있는 객체 래퍼.
- System.IO.Path: 경로 작업(경로 합치기, 확장자/이름 추출 등) 도와주는 클래스.
예제 조금 볼까?
파일 존재 여부 확인
using System.IO;
if (File.Exists("data.txt"))
{
Console.WriteLine("파일 찾았어!");
}
else
{
Console.WriteLine("파일 못 찾았어!");
}
파일 크기 얻기
var info = new FileInfo("data.txt");
Console.WriteLine($"파일 크기: {info.Length} 바이트");
이 예제들은 다음 강의에서 자세히 다룰 거야. 지금은 그냥 구경만 해봐 :)
5. 유용한 팁들
파일 메타데이터: 이름, 확장자, 크기, 날짜 등등
파일을 다룰 때 내용만 중요한 게 아니야 — "파일의 신분증"도 있어:
- 이름 — 사람이 보는 파일 이름.
- 확장자 — .txt, .jpg, .exe, .cs 등: (가끔!) 안에 뭐가 들었는지 알려줘.
- 크기 — 바이트 수.
- 생성/수정 시간 — 파일이 언제 생겼는지, 마지막으로 언제 바뀌었는지 알 수 있어.
- 속성 — 예를 들어: 읽기 전용, 숨김, 시스템 파일 등.
.NET에선 FileInfo, DirectoryInfo 클래스가 이런 작업에 편해(다음 강의에서 다룰 거야).
파일 확장자와 포맷
파일 확장자는 그냥 이름 뒤에 붙는 점(.) 뒤의 부분이야. 예를 들어, document.txt의 확장자는 txt야. 운영체제는 확장자를 보고 뭘로 "열지" 결정해(.jpg면 그림 프로그램, .xls면 Excel 등).
근데 개발자한텐 확장자는 그냥 힌트일 뿐이야. 진짜 파일 포맷은 내용으로만 결정돼. 예를 들어, MyCat.jpg 파일을 텍스트로 열면 "이상한 문자"만 잔뜩 보이고, 그림은 안 보여. 그래서 항상 기억해야 해: 확장자는 보장도 아니고, 그냥 약속일 뿐이야.
파일 읽기/쓰기의 기본 개념
파일은 바이트의 연속이야. C#에서 파일 작업은 보통 이렇게 해:
- 파일 열기 — 읽기, 쓰기(혹은 둘 다) 용도로.
- 읽기 — 데이터를 메모리로 가져오기.
- 쓰기 — 새 데이터를 디스크에 저장.
- 닫기 — 이거 진짜 중요해. 안 닫으면 시스템 리소스를 점유해서, 누군가 파일을 삭제하려 해도 네가 열고 있으면 못 지워.
요즘 .NET API는 이런 걸 잘 챙겨줘. 예를 들어 File 클래스는 파일을 열고, 읽고, 바로 닫아줘. 근데 Stream이나 큰 파일 다룰 땐 신경 써야 해(이건 다음 강의에서 얘기할 거야).
크로스플랫폼에서 알아야 할 것들
요즘 C#은 Windows, Linux, macOS에서 거의 똑같이 돌아가. 그래도 차이가 있긴 해. 제일 흔한 게 구분자(\ vs /) 차이, 파일 이름 길이 제한, 금지된 문자 등등.
그래서 Path.Combine 같은 API나 System.IO.Path의 메서드가 최고야. 이런 애들이 어떤 OS에서도 경로를 제대로 "붙여"줘. 절대 이렇게 쓰지 마:
var filePath = "C:\\Users\\Ivan\\data.txt"; // Windows에서만 돼!
이렇게 쓰는 게 좋아:
var filePath = Path.Combine("Users", "Ivan", "data.txt");
현재 작업 디렉토리 알아내기
가끔 네 파일이 어디 저장될지 알아야 할 때가 있어. 그럴 땐 이 클래스 써봐:
string currentDir = Environment.CurrentDirectory;
Console.WriteLine($"현재 디렉토리: {currentDir}");
참고로, 사용자가 경로를 직접 고르게 하고 싶으면 파일/폴더 선택 다이얼로그나 커맨드라인 인자를 써.
GO TO FULL VERSION