Partners: KDAB Whole Tomato Software

28 January 2019

std::filesystem in C++17 In Detail

C++17 In Detail

On Friday 18th January I’ve pushed another update for the book. This time I rewrote the whole chapter about std::filesystem. Please have a look at what changed and what are the plans.

The book got more than 25 new pages!

std::filesystem - Chapter Rewrite

The book had a filesystem chapter from the start, but it was concise and didn’t contain much information. From the beginning, the plan was to rewrite it, similarly as with the parallel algorithms chapter.

I hoped to do the work in just a few weeks… maybe even before December. But as in other software development related projects, it’s better to multiply the first estimate by 2…3 :)

That’s why I released a new chapter - CSV reader - before this one. By working on a real project, I could learn more and experiment. I needed that to be able to deliver better content.

The refreshed chapter is now 5x larger than the first version! The whole book contains now 306 pages (56 more than I initially planned :))

To sum up, with this refreshed chapter you’ll see:

  • How std::filesystem got into the Standard
  • What the basic types and operations are
  • How you can work with the paths
  • How to handle errors in std::filesystem
  • How to iterate over a directory
  • How to create new directories and files

Example - Filtering Files

Here’s an example, where you can pass a path and then use regex filter and match the file names.

std::vector<FileEntry> CollectFiles(const fs::path& inPath)
{
    std::vector<fs::path> paths;
    if (fs::exists(inPath) && fs::is_directory(inPath))
    {        
        std::filesystem::recursive_directory_iterator dirpos{ inPath };

        std::copy_if(begin(dirpos), end(dirpos), std::back_inserter(paths),
            [](const fs::directory_entry& entry) {
                return entry.is_regular_file();
            }
        );
    }
    std::vector<FileEntry> files(paths.size());
    std::transform(paths.cbegin(), paths.cend(), files.begin(), FileEntry::Create);
    return files;
}

int main(int argc, char* argv[])
{
    try
    {
        const fs::path pathToShow{ argc >= 2 ? argv[1] : fs::current_path() };
        const std::regex reg(argc >= 3 ? argv[2] : "");

        auto files = CollectFiles(pathToShow);

        std::sort(files.begin(), files.end());

        for (auto& entry : files)
        {
            const auto strFileName = entry.mPath.filename().string();
            if (std::regex_match(strFileName, reg))
                std::cout << strFileName << "\tsize: " << entry.mSize << '\n';
        }
    }
    catch (const fs::filesystem_error& err)
    {
        // ...
    }
    catch (const std::exception& ex)
    {
        // ...
    }
}

And to hold the info about the files the code uses the following helper structure:

struct FileEntry
{
    fs::path mPath;
    uintmax_t mSize{ 0 };

    static FileEntry Create(const fs::path& filePath) {
        return FileEntry{ filePath, fs::file_size(filePath) };
    }

    friend bool operator < (const FileEntry& a, const FileEntry& b) noexcept {
        return a.mSize < b.mSize;
    }
};

The code iterates over a directory with recursive_directory_iterator and then filters out only regular files. Later, the function transforms that vector of paths into a vector of FileEntry objects.

When all files are collected the main() function uses std::regex to do the matching.

As a possible optimisation, we can also create a vector of directory_entries rather than paths. This would allow us to fetch the files size faster, as direcotry_entry::file_size is usually cached and filesystem::file_size needs another file access.

Interactive Course

C++17 In Detail Educative

I’m happy to announce that thanks to the collaboration with the team @Educative we published C++17 in Detail as an interactive course!
You can see it… and even preview it for free here:
>> C++17 in Detail: A Deep Dive

It consists of 200 lessons, many quizzes, code snippets… and what’s best is that it has more than 120 playgrounds! That means you can compile and edit code sample directly in the browser… so there’s no need for you to switch back and forth to some compiler/IDE.
I think that such approach increases your learning experience.

And for those of you who are interesting in that form of learning, you can use this coupon:

CPP-DETAIL-20

Use this coupon to buy the course at a much lower price!

Acknowledgements

Special thanks to JFT, Jacek Galowicz, MichaƂ Czaja, and other reviewers who contributed to the chapter!

Book Mentions

So far the book was mentioned in several places.

The Plans

The book is 99% ready!

The remaining parts are related mostly to book polishing and smaller fixes!

For example this week I plan to release a small update for the std::filesystem chapter (adding notes about handling file permissions).

Your Feedback

I appreciate your initial feedback and support! The book has now more than 860 readers (and only six refunds)! That’s not too bad I think :)

Let me know what’s your experience with the book. What would you like to change? What would you like to see more?

Add your feedback/review here:
https://www.goodreads.com/book/show/41447221-c-17-in-detail

You can use this comment site:
https://leanpub.com/cpp17indetail/feedback

Or forum:
https://community.leanpub.com/c/cpp17indetail

Get my free ebook about C++17!

More than 50 pages about the new Language Standard.

C++17 in detail, by Bartlomiej Filipek

© 2017, Bartlomiej Filipek, Blogger platform
Any opinions expressed herein are in no way representative of those of my employers.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.