본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : std::filesystem

by snowoods 2025. 9. 3.

Modern C++

 

std::filesystem

 

개요

std::filesystem은 C++17에서 도입된 파일 시스템 라이브러리로, 파일과 디렉토리 조작을 위한 다양한 기능을 제공합니다. 이 라이브러리는 플랫폼 독립적인 방식으로 파일 시스템을 다룰 수 있게 해주며, 경로 조작, 파일 속성 조회, 디렉토리 순회 등의 작업을 수행할 수 있습니다.

 

C++ 버전별 주요 키워드 도입 시기

  • C++17: std::filesystem 네임스페이스와 주요 클래스들(path, directory_iterator 등)이 표준 라이브러리에 추가
  • C++20: std::filesystem::pathoperator<=> (three-way comparison) 추가

 

내용 설명

std::filesystem은 다음과 같은 주요 기능을 제공합니다:

  1. 경로 조작: path 클래스를 통해 플랫폼 독립적인 경로 처리가 가능합니다.
  2. 파일 속성 조회: 파일 크기, 수정 시간, 권한 등의 메타데이터를 확인할 수 있습니다.
  3. 파일 시스템 작업: 파일/디렉토리 생성, 복사, 이동, 삭제 등의 작업을 수행할 수 있습니다.
  4. 디렉토리 순회: directory_iterator를 사용하여 디렉토리 내용을 순회할 수 있습니다.

 

예제 코드

#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

int main()
{
    // 경로 조작 예제
    auto workspace_path = fs::path{"C:\\Users\\Jan\\Dektop\\UdemyCppEng"};
    auto chapter_path = workspace_path;
    chapter_path /= "Chapter5";
    std::cout << chapter_path << '\n';

    // 현재 경로에 파일 추가
    auto current_path = fs::current_path();
    current_path /= "file_systems.cc";
    std::cout << current_path << '\n';

    // 경로 구성 요소 출력
    std::cout << "relative_path: " << current_path.relative_path() << '\n';
    std::cout << "parent_path: " << current_path.parent_path() << '\n';
    std::cout << "filename: " << current_path.filename() << '\n';
    std::cout << "stem: " << current_path.stem() << '\n';
    std::cout << "extension: " << current_path.extension() << '\n';

    // 파일 속성 확인
    std::cout << "exists: " << std::boolalpha << fs::exists(current_path) << '\n';
    std::cout << "is_regular_file: " << std::boolalpha
              << fs::is_regular_file(current_path) << '\n';
    std::cout << "is_directory: " << std::boolalpha
              << fs::is_directory(current_path) << '\n';

    // 디렉토리 순회
    std::cout << "\nDirectory contents:\n";
    for (const auto& entry : fs::directory_iterator(fs::current_path()))
    {
        std::cout << entry.path() << '\n';
    }

    // 새 디렉토리 생성 및 파일 복사
    auto new_directory_path = fs::current_path() / "test";
    if (!fs::exists(new_directory_path))
    {
        fs::create_directory(new_directory_path);
    }

    auto new_file_path = new_directory_path / "FileSystemCopy.cc";
    if (!fs::exists(new_file_path))
    {
        fs::copy_file(current_path, new_file_path);
    }
}

 

실행 결과

C:\Users\Jan\Dektop\UdemyCppEng\Chapter5
/current/path/to/executable/file_systems.cc
relative_path: current/path/to/executable/file_systems.cc
parent_path: /current/path/to/executable
filename: "file_systems.cc"
stem: "file_systems"
extension: ".cc"
exists: true
is_regular_file: true
is_directory: false

Directory contents:
/path/to/executable/file1.txt
/path/to/executable/file2.txt
/path/to/executable/dir1
...

 

활용팁

  1. 크로스 플랫폼 호환성: std::filesystem은 운영체제에 상관없이 일관된 인터페이스를 제공하므로, 플랫폼별로 다른 코드를 작성할 필요가 없습니다.
  2. 경로 구분자: operator/operator/=를 사용하면 운영체제에 맞는 경로 구분자를 자동으로 처리해줍니다.
    • operator/는 경로를 결합한 새로운 path 객체를 반환합니다.
    • operator/=는 현재 경로 객체에 경로를 추가하여 수정합니다. (예: path /= "subdir")
    • 예시:
      fs::path p1 = "C:\\Users";
      fs::path p2 = p1 / "Documents";  // p1은 변경되지 않음
      p1 /= "Downloads";               // p1이 직접 수정됨 ("C:\\Users\\Downloads")
  3. 예외 처리: 파일 시스템 작업은 실패할 수 있으므로, std::filesystem::filesystem_error 예외에 대한 처리를 고려해야 합니다.
  4. 재귀적 디렉토리 순회: recursive_directory_iterator를 사용하면 하위 디렉토리까지 재귀적으로 순회할 수 있습니다.
  5. 파일 복사 옵션: fs::copy_options를 사용하여 파일 복사 동작을 세밀하게 제어할 수 있습니다.
  6. 경로 조합 시 주의사항:
    • operator/=operator/는 자동으로 경로 구분자를 추가하므로 직접 구분자를 포함시키지 않아도 됩니다.
    • 예를 들어 path /= "subdir/" 대신 path /= "subdir"로 사용하는 것이 더 안전합니다.
    • 경로의 시작이 구분자로 시작하면 절대 경로로 처리됩니다.