Coding Memo

std::filesystem 본문

Language/C++

std::filesystem

minttea25 2024. 9. 19. 19:52

C++17부터 추가된 파일 시스템 라이브러리에서 파일과 디렉터리에 관한 여러가지 유틸을 사용할 수 있다.

자주 사용할 것 같은 메서드와 멤버 변수들을 간단하게 정리해 보았다.

Header

filesystem

Namespace

std::filesystem


1. 현재 경로 (working directory, current path)

 

current_path()

현재 실행중인 경로(working directory)를 반환한다. (return: std::filesystem::path)

참고로, 반환된 경로는 절대 경로(absolute path)이다.

 

current_path(const std::filesystem::path& p)

현재 경로를 p로 변경한다. (return: void)

마찬가지로 p가 상대경로로 지정했더라도 current_path는 절대 경로로 지정된다.

namespace fs = std::filesystem;

int main()
{
    fs::path current = fs::current_path();
    std::cout << "Current path: " << current << std::endl;

    fs::current_path("..\\Resources"); // 현재 경로를 ..\Resources 로 변경
    std::cout << "Changed current path: " << fs::current_path() << std::endl;

    return 0;
}


// output
Current path: "C:\\Users\\(생략)\\BlackBoard20"
Changed current path: "C:\\Users\\(생략)\\Resources"

 

 

2. 파일 존재, 디렉터리 존재

exists

주어진 path(std::filesystem::path)가 존재하는지 여부를 반환한다.

path가 파일인 경우 확장자까지 온전하게 포함이 되어 있어야 한다.

return: bool

namespace fs = std::filesystem;

int main()
{
    // c.png가 존재하더라도, path를 ..\\Resources\\c 로 하면 파일시스템은 해당 파일을 찾지 못한다.
    fs::path target("..\\Resources\\c.png");
    std::cout << "Path is " << target << std::endl;

    if (fs::exists(target))
    {
        std::cout << "The path exists" << endl;
    }
    else
    {
        std::cout << "The path does not exist." << endl;
    }

    return 0;
}

 

 

3. 절대경로, 상대경로

absolute, relative

    return
absolute(path) 주어진 path를 절대경로로 변경 -
relative(path) 주어진 path를 상대경로로 변경 -

 

absolute는 주어진 path를 절대 경로로 변경하고, relative는 주어진 path를 상대 경로로 변경한다.

(absolute는 경로에 포함된 symbolic link는 해석하지 않고 그대로 절대경로로 변경한다.)

namespace fs = std::filesystem;

int main()
{
    fs::path original("..\\Resources\\c.png");
    std::cout << "Original path: " << original << endl;

    auto absolute = fs::absolute(original);
    std::cout << "After absolute: " << absolute << endl;

    auto relative = fs::relative(absolute);
    std::cout << "After relative: " << relative << endl;
}


// output
Original path: "..\\Resources\\c.png"
After absolute: "C:\\Users\\(생략)\\Blackboard\\Resources\\c.png"
After relative: "..\\Resources\\c.png"

 

Note: 절대경로와 상대경로 외에도, canonical_path도 존재한다. canonical_path는 absolute와 같이 절대경로를 반환하긴 하지만, path가 symbolic link를 포함하고 있을 때, 해당 링크가 가리키는 실제 파일 경로로 해석한 절대경로를 반환한다. 즉 path에 포함된 symbolic link를 실제 경로로 해석해준다. (유일하게 존재하는 절대 경로를 반환한다고 생각하면 된다.)

 

 

 

4. 파일 사이즈

file_size

해당 경로의 파일 사이즈 값 (bytes) 을 반환한다. 만약 경로가 파일이 아닌 디렉터리라면, 0을 반환한다.

namespace fs = std::filesystem;

int main()
{
    fs::path file("..\\Resources\\c.png");
    std::cout << "File size of " << file << ": " << fs::file_size(file) << endl;

    fs::path dir("..\\Resources");
    std::cout << "File size of " << dir << ": " << fs::file_size(dir) << endl;

    return 0;
}


// output
File size of "..\\Resources\\c.png": 23890
File size of "..\\Resources": 0

 

 

 

5. 경로 순회

directory_iterator 클래스와 recursive_directory_iterator 클래스로 경로에 있는 디렉터리와 파일을 순회하면서 확인할 수 있다.

 

 

directory_iterator

해당 path에 있는 파일과 디렉터리들을 순회한다. 각 값은 directory_entry 클래스이다.

namespace fs = std::filesystem;

int main()
{
    fs::path current = fs::current_path();
    for (auto& entry : fs::directory_iterator(current))
    {
        std::cout << entry << endl;
    }

    return 0;
}


// output
"C:\\Users\\[...]\\BlackBoard20.vcxproj"
"C:\\Users\\[...]\\BlackBoard20.vcxproj.filters"
"C:\\Users\\[...]\\BlackBoard20.vcxproj.user"
"C:\\Users\\[...]\\BlackBoard20\\flatbuffer_sample"
"C:\\Users\\[...]\\BlackBoard20\\headers.h"
"C:\\Users\\[...]\\BlackBoard20\\main.cpp"
"C:\\Users\\[...]\\BlackBoard20\\x64"

 

 

recursive_directory_iterator

주어진 경로에 있는 파일 및 디렉터리를 recursive하게 순회한다. 마찬가지로 순회 값은 directory_entry 클래스이다.

namespace fs = std::filesystem;

int main()
{
    fs::path current = fs::current_path();
    for (auto& entry : fs::recursive_directory_iterator(current))
    {
        std::cout << entry << endl;
    }

    return 0;
}


// output
"C:\\Users\\[...]\\BlackBoard20.vcxproj"
"C:\\Users\\[...]\\BlackBoard20.vcxproj.filters"
"C:\\Users\\[...]\\BlackBoard20.vcxproj.user"
"C:\\Users\\[...]\\flatbuffer_sample"
...
"C:\\Users\\[...]\\x64"
"C:\\Users\\[...]\\x64\\Debug"
"C:\\Users\\[...]\\x64\\Debug\\BlackBoard20.Build.CppClean.log"
...
"C:\\Users\\[...]\\x64\\Debug\\vc143.idb"
"C:\\Users\\[...]\\x64\\Debug\\vc143.pdb"

 

Note: 단순 path 클래스도 iterator가 구현이 되어 있다. 이 값은 해당 경로의 각 디렉터리 이름를 순회한다. ('\\' 를 delimeter로 하여 볼륨 구분을 제외하고 tokenizer한 결과를 순회한다.)

e.g. "C:\\users\\blackboard\\test" => "C:", "\\", "users", "blackboard", "test"


위에서 간단하게 정리한 메서드나 클래스 말고도, 파일 시스템에서 기본적으로 사용하는, 파일/디렉터리 삭제, 파일/디렉터리 생성, 이름 변경, 파일/디렉터리 복사 등의 메서드들도 지원한다.

 

아래 레퍼런스를 참고하자.

https://en.cppreference.com/w/cpp/filesystem

 

Filesystem library (since C++17) - cppreference.com

The Filesystem library provides facilities for performing operations on file systems and their components, such as paths, regular files, and directories. The filesystem library was originally developed as boost.filesystem, was published as the technical sp

en.cppreference.com

 

'Language > C++' 카테고리의 다른 글

Singleton 패턴  (0) 2024.09.26
std::sort와 std::list.sort  (1) 2024.09.26
dllexport / dllimport (MSVC)  (0) 2024.09.04
[winsock] getpeername 호출 시, WSAENOTCONN(10057) 에러  (0) 2024.05.23
[C++] Concurrent 우선순위 큐 (with lock)  (0) 2024.05.13