Coding Memo
std::filesystem 본문
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
'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 |