C++17: std::byte and std::filesystem

C++17: std::byte and std::filesystem


This is a crosspost from www.ModernesCpp.com.

?My post C++17 - What's New in the Library was fine for the first overview. Today, I will look deeper into the new library. 

Let's start with something totally new that I didn't mention in my previous posts:

std::byte

std::byte is a distinct type implementing the concept of a byte as specified in the C++ language definition. Now we know, what a byte is.Therefore, a byte is not an integer or a character and therefore not open to programmer errors. Its job is to access object storage. Consequently, its interface consists only of methods for bitwise logical operations.

You can use the function std::to_integer(std::byte b) to convert a std::byte to an integer type and the call std::byte{integer} to do it the other way around. integer has to be a non-negative value smaller than std::numeric_limits<unsigned_char>::max().

Now to something, you already know.

The filesystem library

I gave you in the post C++17 - What's New in the Library a first impression of the filesystem library. The library is based on the three concepts file, file name, and path. Files can be directories, hard links, symbolic links or regular files. Paths can be absolute, canonical or relative. A canonical path is a path including no symlinks, "." or ".." elements.

You can create and remove directories, iterate over them or check properties of files.

But there is more to it. So I will now focus on features that are not so obvious. At least for me. I show you,

  • how you can manipulate the file permissions,
  • read the time values of a file,
  • and even get the free and available space of the filesystem.

I used for my examples the std::experimental::filesystem namespace. Therefore, I was able to run and check them on cppreference.com. Afterwards, I adjusted the sources to the upcoming official names. That means, I replaced the header <experimental/filesystem> by <filesystem> and the namespace std::experimental::filesystem by std::filesystem.

Let's start with file permissions.

Permissions

The permission is represented by the class std::filesystem::perms. It is a BitmaskType and can, therefore, be manipulated by bitwise operations. The access permissions are based on POSIX.

The program from cppreference.com shows, how you can read and manipulate the owner, group, and other (world) bits of a file.

I created in line 26 a new file. Thanks to the global function std::filesystem::status::permissions, I get the permissions of the file and can display them in the function printPerms (line 10-21). After I set the constant, std::filesystem::add_perms in line 31, I can add permissions to the owner and the group of the file. Doing it the other way around, I set the constant std::filesystem::remove_perms in line 36. Therefore, I can remove the write bits for all.

Here is the output of the program.

A file has not only the notion of permission but also of time.

Time values

Thanks to the global function std::filesystem::last_write_time, I can read and write the last write time of a file. Here is the example, based on the example of en.cppreference.com.

In line 15, I get the write time of the newly created file. I use ftime in line 17 to initialize std::chrono::system_clock. ftime is of type std::filesystem::file_time_type which seem on the server an alias for std::chrono::system_clock. That is fine. Therefore, I can initialize std::localtime in line 18 and present the calendar time in a textual representation. If I use std::gmtime instead of std::localtime (line 18), nothing will change. That puzzled me because the Coordinated Universal Time (UTC) differs 2 hours from the local time in German. But that's okay because that will not hold for the server. UTS and local time are the same on the server. 

Here is the output of the program. In addition, you see the local time in Germany. I got it by adding 2 hours (line 21) to the last write time of the file.

Now to the feature that astonished me the most.

Space info

The global function std::filesystem::space returns a std::filesystem::space_info object that has the three members capacity, free, and available.

  • capacity: total size of the filesystem
  • free: free space on the filesystem
  • available: free space to a non-privileged process (maybe equal or less than free)

All sizes are in bytes. The output of the following program is from cppreference.com. All the paths I tried were on the same filesystem. Therefore, I always get the same answer.

 Here are the numbers.

 Here are the numbers.

What's next?

Our journey through the details of C++17 goes on. The next post will continue with std::string_view.





Marina Ektova

Expert software engineer at TomTom

7 年

Why getPerms is not something like printPerms, as it doesn't return anything?

Joel Young

ML Infrastructure | Gen AI, Leadership

7 年

Line 17 on first filesystem example is interesting...

要查看或添加评论,请登录

Rainer Grimm的更多文章

社区洞察

其他会员也浏览了