One of the new supported C++ headers in Visual Studio 2012 is <filesystem>. It defines types and functions for working with files and folders. It’s not a C++11 header, but it’s part of the TR2 proposal, hence the namespace it uses, std::tr2::sys. Among others, the header provides functionality for creating, renaming, deleting, or checking the state and type of a path. It also offers support for iterating through the content of a folder. Unfortunately, the MSDN documentation is not that good; it’s rather a reference documentation, missing any examples.
Here is a simple sample that demonstrates some of the features from this new header.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <iostream> #include <filesystem> int main() { std::tr2::sys::path mypath="c:\\temp"; std::cout << "path_exists = " << std::tr2::sys::exists(mypath) << '\n'; std::cout << "is_directory = " << std::tr2::sys::is_directory(mypath) << '\n'; std::cout << "is_file = " << std::tr2::sys::is_empty(mypath) << '\n'; auto lasttime = std::tr2::sys::last_write_time(mypath); char buffer[50] = {0}; ctime_s(buffer, sizeof(buffer), &lasttime); std::cout << "last_write = " << buffer << '\n'; std::tr2::sys::recursive_directory_iterator endit; std::tr2::sys::recursive_directory_iterator it(mypath); for(; it != endit; ++it) { auto& apath = it->path(); if(std::tr2::sys::is_directory(apath) && std::tr2::sys::is_symlink(apath)) { it.no_push(); } print(apath, it.level()); } return 0; } |
And the output is
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
path_exists = 1 is_directory = 1 is_file = 0 last_write = Tue Jan 29 21:45:39 2013 +dir1 ├+dir11 │├+dir111 ││├+dir1111 │││├-file1111.txt │││├-file1112.txt ││├-file111.txt ││├-file112.txt │├-file11.txt │├-file12.txt ├+dir12 ├-file11.txt ├-file12.txt ├-file13.txt -file1.txt -file2.txt |
What’s missing from the code above is the print method, but that’s just about formatting details:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void print(const std::tr2::sys::path& path, int level) { for(int i = 0; i < level-1; ++i) std::cout << (char)179; if(level > 0) cout << (char)195; if(std::tr2::sys::is_directory(path)) std::cout << "+"; else if(std::tr2::sys::is_regular_file(path)) std::cout << "-"; else std::cout << " "; std::cout << path.filename() << std::endl; } |