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.
#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
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:
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;
}