C++ Filesystem 빠른 참조 | "파일시스템" C++17 라이브러리 가이드
이 글의 핵심
C++ Filesystem에 대해 정리한 개발 블로그 글입니다. #include <filesystem> #include <iostream> namespace fs = std::filesystem;
기본 사용법
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int main() {
fs::path p = "/home/user/file.txt";
cout << "경로: " << p << endl;
cout << "파일명: " << p.filename() << endl;
cout << "확장자: " << p.extension() << endl;
cout << "디렉토리: " << p.parent_path() << endl;
}
경로 조작
fs::path p1 = "/home/user";
fs::path p2 = "documents";
fs::path p3 = "file.txt";
// 경로 결합
fs::path full = p1 / p2 / p3;
cout << full << endl; // /home/user/documents/file.txt
// 확장자 변경
fs::path file = "test.txt";
file.replace_extension(".md");
cout << file << endl; // test.md
// 절대 경로
fs::path rel = "file.txt";
fs::path abs = fs::absolute(rel);
cout << abs << endl;
파일 존재 확인
fs::path p = "test.txt";
if (fs::exists(p)) {
cout << "파일 존재" << endl;
}
if (fs::is_regular_file(p)) {
cout << "일반 파일" << endl;
}
if (fs::is_directory(p)) {
cout << "디렉토리" << endl;
}
실전 예시
예시 1: 디렉토리 순회
#include <filesystem>
namespace fs = std::filesystem;
void listFiles(const fs::path& dir) {
for (const auto& entry : fs::directory_iterator(dir)) {
cout << entry.path() << endl;
if (entry.is_regular_file()) {
cout << " 파일, 크기: " << entry.file_size() << " bytes" << endl;
} else if (entry.is_directory()) {
cout << " 디렉토리" << endl;
}
}
}
int main() {
listFiles(".");
}
예시 2: 재귀 순회
void listFilesRecursive(const fs::path& dir) {
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
// 들여쓰기
int depth = distance(dir.begin(), entry.path().begin());
cout << string(depth * 2, ' ') << entry.path().filename() << endl;
}
}
int main() {
listFilesRecursive(".");
}
예시 3: 파일 검색
#include <vector>
vector<fs::path> findFiles(const fs::path& dir, const string& extension) {
vector<fs::path> result;
for (const auto& entry : fs::recursive_directory_iterator(dir)) {
if (entry.is_regular_file() && entry.path().extension() == extension) {
result.push_back(entry.path());
}
}
return result;
}
int main() {
auto cppFiles = findFiles(".", ".cpp");
cout << "C++ 파일 " << cppFiles.size() << "개:" << endl;
for (const auto& file : cppFiles) {
cout << " " << file << endl;
}
}
예시 4: 디렉토리 생성
void createDirectoryStructure() {
fs::path base = "project";
// 디렉토리 생성
fs::create_directory(base);
fs::create_directory(base / "src");
fs::create_directory(base / "include");
fs::create_directory(base / "build");
// 중첩 디렉토리 생성
fs::create_directories(base / "src" / "utils" / "helpers");
cout << "디렉토리 구조 생성 완료" << endl;
}
int main() {
createDirectoryStructure();
}
파일 작업
// 파일 복사
fs::copy("source.txt", "dest.txt");
// 파일 이동
fs::rename("old.txt", "new.txt");
// 파일 삭제
fs::remove("file.txt");
// 디렉토리 삭제 (재귀)
fs::remove_all("directory");
// 파일 크기
uintmax_t size = fs::file_size("file.txt");
// 수정 시간
auto time = fs::last_write_time("file.txt");
경로 정규화
fs::path p = "/home/user/../user/./file.txt";
// 정규화
fs::path canonical = fs::canonical(p);
cout << canonical << endl; // /home/user/file.txt
// 상대 경로
fs::path rel = fs::relative("/home/user/file.txt", "/home");
cout << rel << endl; // user/file.txt
자주 발생하는 문제
문제 1: 예외 처리
// ❌ 예외 무시
fs::remove("file.txt"); // 파일 없으면 예외
// ✅ 예외 처리
try {
fs::remove("file.txt");
} catch (const fs::filesystem_error& e) {
cout << "에러: " << e.what() << endl;
}
// ✅ 에러 코드 사용
error_code ec;
fs::remove("file.txt", ec);
if (ec) {
cout << "에러: " << ec.message() << endl;
}
문제 2: 심볼릭 링크
fs::path link = "symlink";
// ❌ 심볼릭 링크 따라감
if (fs::is_regular_file(link)) {
// 링크 대상 체크
}
// ✅ 심볼릭 링크 자체 체크
if (fs::is_symlink(link)) {
cout << "심볼릭 링크" << endl;
}
문제 3: 권한 문제
// ❌ 권한 없는 디렉토리
for (const auto& entry : fs::directory_iterator("/root")) {
// 예외 발생
}
// ✅ 예외 처리
try {
for (const auto& entry : fs::directory_iterator("/root")) {
cout << entry.path() << endl;
}
} catch (const fs::filesystem_error& e) {
cout << "접근 거부" << endl;
}
파일 정보
fs::path p = "file.txt";
// 권한
auto perms = fs::status(p).permissions();
// 크기
uintmax_t size = fs::file_size(p);
// 수정 시간
auto mtime = fs::last_write_time(p);
// 공간 정보
fs::space_info space = fs::space(".");
cout << "전체: " << space.capacity << endl;
cout << "사용 가능: " << space.available << endl;
FAQ
Q1: filesystem은 언제 사용하나요?
A:
- 파일/디렉토리 작업
- 경로 조작
- 파일 검색
- 빌드 도구
Q2: 기존 방식과 차이는?
A:
- 크로스 플랫폼
- 타입 안전
- 예외 안전
- 더 편리한 API
Q3: 성능은?
A: 기존 시스템 콜과 비슷하거나 약간 느립니다.
Q4: 에러 처리는?
A:
- 예외 버전 (기본)
- error_code 버전 (예외 없음)
Q5: 경로 구분자는?
A: 자동으로 플랫폼에 맞게 변환됩니다 (/ 또는 \).
Q6: Filesystem 학습 리소스는?
A:
- cppreference.com
- “C++17: The Complete Guide”
- Boost.Filesystem 문서
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- C++ Filesystem | “파일시스템 라이브러리” 가이드
- C++ File Status | “파일 상태” 가이드
- C++ File Operations | “파일 연산” 가이드
관련 글
- C++ std::filesystem 완벽 가이드 | 경로·디렉토리·파일·권한 한 번에 정리
- C++ Directory Iterator |
- C++ File Operations |
- C++ File Status |
- C++ Filesystem 개념 정리 |