[C++기초] 19. 파일시스템, 모듈시스템
INDEX
파일 시스템
파일 시스템
- C++17의 새로운 라이브러리
- C++14나 그 이전에는 파일 시스템과 다음과 같은 구성 요소에 대한 연산을 할 방법이 없었음
- 경로
- 일반 파일
- 디렉터리
- 파일 읽기와 쓰기에 관한 라이브러리가 아님
- 파일 속성 변경, 디렉터리 순회, 파일 복사 등에 관한 라이브러리
- 이 모든걸 std::fs로 할 수 있음
파일시스템 연산
- 플랫폼 공통적인 방법으로 경로 합치기
- 파일과 디렉터리를 복사, 이름 바꾸기, 삭제
- 디렉터리에서 파일, 디렉터리 목록 가져오기
- 파일 권한 읽기 및 설정
- 파일 상태 읽기 및 설정
예시 : 경로 합치기
#include<filesystem> //컴파일러에 따라 std::filesystem 네임스페이스 대신 std::experimental::filesystem::v1을 사용해야 될 수도 있음 namespace fs = std::experimental::filesystem::v1; int main() { fs::path path1 = "D:\\Lecture;" fs::path paht2 = "example"; path1 /= path2; fs::path path3 = "D:\\Lecture;" fs::path paht4 = "example"; path += path4; return 0; }
std::filesystem::path::operator/=
path& operator/=(const path& p)
-
p를 현재 경로의 서브폴더로 덧붙인다
-
리눅스와 윈도우 모두에서 작동
std::filesystem::path path1 = "D:\\Lecture"; path /= "examples"; // D:\Lecture\examples;
std::filesystem::path path1 = "D:\\Lecture"; path1 /= "\examples"; // D:\examples;
std::filesystem::copy()
void copy(const std::filesystem::path& from, const std::filesystem::path& to);
void copy(const std::filesystem::path& from, const std::filesystem::path& to, std::filesystem::copy_options options);
- 파일 또는 디렉터리를 복사한다
예시 : 파일 또는 디렉터리 복사하기
#include <filesystem> namespace fs = std::experimental::filesystem::v1; int main() { fs::path originalTextPath = "C:\\examples\\myRank.txt"; fs::path copiedTextPath = "C:\\examples\\copiedMyRank.txt"; fs::path originalDirPath = "C:\\examples\\folder1"; fs::path copiedDirPath1 = "C:\\examples\\copiedfolder1"; fs::path copiedDirPath2 = "C:\\examples\\copiedfolder2"; fs::copy(originalTextPath, copiedTextPath); // 파일 복사 fs::copy(originalDirPath, copiedDirPath1); // 디렉터리 복사 (비재귀적으로) fs::copy(originalDirPath, copiedDirPath2, copy_options::recursive); // 디렉터리 복사 (재귀적으로) return 0; }
std::filesystem::rename()
- 파일 또는 디렉터리의 이름을 바꾸거나 이동시킨다
void rename( const std::filesystem::path& old_p, const std::filesystem::path& new_p);
예시 : 파일 또는 디렉터리 이름 바꾸기/이동
#include <experimental/filesystem> namespace fs = std::experimental::filesystem::v1; int main() { fs::path filePath = "C:\\examples\\myRank.txt"; fs::path renamedPath = "C:\\examples\\folder1\\rank.txt"; fs::rename(filePath, renamedPath); return 0; }
std::filesystem::remove()/remove_all()
- 파일이나 빈 디렉터리 삭제
bool remove(const std::filesystem::path& p);
- p안에 들어있는 내용물들 삭제
std::uintmax_t remove_all(const std::filesystem::paht& p);
- 예시
fs::remove("C:\\examples\\myRank.txt"); // myRank.txt를 삭제 fs::remove_all("C:\\examples"); // example 폴더 안에 있는 모든 것을 삭제
예시 : 파일 또는 디렉터리 삭제
#include <experimental/filesystem> namespace fs = std::experimental::filesystem::v1; int main() { fs::path currentPath = fs::current_path(); fs::create_directiories(currentPath / "data");//프로젝트 폴더에 새 폴더를 만듦 fs::remove(correntPath / "data"); return 0; }
std::filesystem::recursive_directory_iterator()
class recursive_directory_iterator;
-
디렉터리의 요소들을 순회한다
-
그리고 재귀적으로 하위 디렉터리의 요소들을 순회한다
for(auto& path : fs::recursive_directory_iterator("C:\\Lecture\\FilesystemExample")) { std::cout << path <<std::endl; }
예시 : 디렉터리의 파일 목록 가져오기
#include <experimental/filesystem> namespace fs = std::experimental::filesystem::v1; int main() { for(auto& path : fs::recursive_directory_iterator("C:\\Lecture\\FilesystemExample")) { std::cout << path <<std::endl; } return 0; }
Result
std::filesystem::status()
std::filesystem::file_status status(const std::filesystem::path& p);
-
파일 상태를 반환한다
- 블록 파일(block file), 디렉터리, FIFO, 소켓(socket), …
std::filesystem::file_status status = std::filesystem::status("C:\\example");
std::filesystem::permissions()
perms permissions();
-
파일 권한을 반환한다
- 소유자의 읽기, 쓰기, 실행
- 소유자와 같은 그룹의 읽기, 쓰기, 실행
- 외부인의 읽기, 쓰기, 실행
std::filesystem::perms permissions = std::filesystem::status("C:\\examples\\folder1\\rank.txt").permissions();
예시 : 파일 속성(권한) 읽기
#include <experimental/filesystem> namespace fs = std::experimental::filesystem::v1; void PrintPermission(fs:;perms permission) { std::cout<<(permission & fs::perms::owner_read) != fs::perms::none ? "r" : "-") <<((permission & fs::perms::owner_write) != fs::perms::none ? "w" : "-") <<((permission & fs::perms::owner_exec) != fs::perms::none ? "x" : "-") <<((permission & fs::perms::group_read) != fs::perms::none ? "r" : "-") <<((permission & fs::perms::group_write) != fs::perms::none ? "w" : "-") <<((permission & fs::perms::group_exec) != fs::perms::none ? "x" : "-") <<((permission & fs::perms::others_read) != fs::perms::none ? "r" : "-") <<((permission & fs::perms::others_write) != fs::perms::none ? "w" : "-") <<((permission & fs::perms::others_exec) != fs::perms::none ? "x" : "-") << std::endl; } int main() { fs::path filePath = "C:\\examples\\folder1\\rank.txt"; PrintPermission(fs::status(filePath).permissions()); return 0; }
Result
모듈 시스템
모듈 시스템
-
C++17까지도 여전히 C++ 표준으로 들어오지 않음
-
허나 비주얼 스튜디오에서 /experimental:module 플래그를 활성화해서 사용할 수 있음
-
표준이 된다면
-
-
컴파일이 엄청나게 빨라짐
-
.cpp와 .h파일로 나눌 필요가 없어짐
-
- 이건 컴파일 속도를 높이기 위한 것이었음
- Java의 패키지처럼 작동
-
-
여전히 앞에 시련이 놓여 있음
-
- .cpp와 .h둘 다 있는 레거시 코드는 어떻게 처리하나요?
- 만약 #define을 너무 많이 쓰고 있으면?