File System Library in C++17
Last Updated :
05 Oct, 2023
In this article, we will learn about the File System library in C++17 and with examples. <filesystem> header was added in C++17 and introduces a set of classes, functions, and types that simplify file system operations. In simple words, we can say that the filesystem library provides tools that help us to simplify working with files and directories.
In earlier versions, performing file and directory operations was often a bulky and mistake-susceptible task as it required the use of platform-specific functions and libraries. The file system library was added to cope with these troubles, offering a portable and standardized way to paint with the file system.
Syntax
To use the features of the file system library, we have to import <filesystem> header using #include preprocessor.
#include <filesystem>
All the identifiers of <filesystem> headers are defined inside the std::filesystem namespace.
Classes in <filesystem> Header
The following are some commonly used classes of file system libraries.
S. No.
|
Class
|
Description
|
1
|
filesystem::path |
The path class represents the path of the directory or the file. |
2
|
filesystem::copy_options |
This class represents the available copy options. |
3
|
filesystem::directory_options |
Represents the options for iterating through directory contents. |
4
|
filesystem::filesystem_error |
This class defines the exceptions that are thrown by the filesystem functions in case of errors. |
5
|
filesystem::file_status |
This class stores information about the type of the file and available permissions. |
6
|
filesystem::file_time_type |
It represents file time values |
7
|
filesystem::perms |
This function stores the information about the file access permission. |
8
|
filesystem::perm_options |
It specifies the semantics of permissions operations. |
9
|
filesystem::space_info |
This struct stores the data about the storage in the specified path. |
10
|
filesystem::file_type: |
It is used to represent different types of a file or directory. |
Examples of File System library
Example 1: Creating a Directory and File
In this example, we will create a new file in a newly created directory. The parent directory looks like this before execution:
Parent Directory Before Execution
C++
#include <filesystem>
#include <fstream>
#include <iostream>
using namespace std;
using namespace std::filesystem;
int main()
{
path directorypath = "mydirectory" ;
if (!exists(directorypath)) {
create_directory(directorypath);
cout << "Directory created: " << directorypath
<< endl;
}
path filepath = directorypath / "my_file.txt" ;
ofstream file(filepath);
if (file.is_open()) {
file << "Hello, FileSystem!" ;
file.close();
cout << "File created: " << filepath << endl;
}
else {
cerr << "Failed to create file: " << filepath
<< endl;
}
return 0;
}
|
Output
Directory created: "mydirectory"
File created: "mydirectory/my_file.txt"
Explanation
In this example, a directory is created named “mydirectory”. It checks if the directory exists and creates it if no longer. Sooner or later, a file named “my_file.Txt” is defined within this directory. The code then opens this file for writing using std::ofstream. If a success, it writes the text “Hello, FileSystem!” to the file and closes it. If any errors occur in the directory of the listing or file advent procedure, suitable error messages are displayed.
Parent Directory After Execution
New Directory
Contents of New File
Example 2: Listing Files in a Directory
C++
#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::filesystem;
int main()
{
path directorypath = "" ;
if (exists(directorypath)
&& is_directory(directorypath)) {
for ( const auto & entry :
directory_iterator(directorypath)) {
cout << "File: " << entry.path() << endl;
}
}
else {
cerr << "Directory not found." << endl;
}
return 0;
}
|
Output
File: "mydirectory/my_file.txt"
File: "mydirectory/my_file2.txt"
File: "mydirectory/my_file3.txt"
File: "mydirectory/my_file4.txt"
Explanation
In this example, first, we define the directorypath to indicate the target directory. Then we wrote the condition to check if the directory exists or not using fs::exists() and fs::is_directory(). If it exists, it iterates through its contents using a range-based for loop with fs::directory_iterator(), and prints each item’s path to the standard output.
Example 3: Renaming a File
C++
#include <filesystem>
#include <iostream>
using namespace std;
using namespace std::filesystem;
int main()
{
path oldFilePath = "mydirectory/my_file.txt" ;
path newFilePath = "mydirectory/renamed_file.txt" ;
if (exists(oldFilePath)) {
rename (oldFilePath, newFilePath);
cout << "File renamed to: " << newFilePath << endl;
}
else {
cerr << "File not found: " << oldFilePath << endl;
}
return 0;
}
|
Output
File renamed to: "mydirectory/renamed_file.txt"
Explanation
In this example, first, we define the path for the old file and the new file. Then, wrote a condition to check if the old file exists in the directory or not with fs::exists(), and if it is discovered, then rename it using fs::rename(). A success message will be displayed with the new file path. and if the old file isn’t found, it prints an error message.
Advantages and Features of <filesystem>
Let’s explore some of the key features provided by the <filesystem> library:
- Path Manipulation: The file system library introduces the std::filesystem::path class to represent file system paths. This class encapsulates the platform-specific path representation and provides an easy way to manipulate and inspect paths.
- File and Directory Operations: The file system library includes functions to perform common file and directory operations such as creating, removing, renaming, and checking for the existence of files and directories.
- Error Handling: The <filesystem> library provides exceptions to handle errors during file system operations. You can catch exceptions like std::filesystem::filesystem_error to gracefully handle failures.
- Portable Code: One of the main advantages of using <filesystem> is the portability it brings to your code. Since it abstracts platform-specific details, you can write code that works consistently across different operating systems.
Share your thoughts in the comments
Please Login to comment...