<filesystem> header in Visual Studio 2012

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;
}