std::filesystem
does not provide built-in support for watching a directory for changes. To achieve this, you need to use platform-specific APIs or third-party libraries.
On Windows, you can use the ReadDirectoryChangesW()
function to watch for directory changes. Here’s a basic example using Windows API:
#include <windows.h>
#include <iostream>
void watch_directory(
const std::wstring &directory) {
HANDLE dir_handle = CreateFileW(
directory.c_str(),
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE
| FILE_SHARE_DELETE,
nullptr,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
nullptr)
;
if (dir_handle == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open directory\n";
return;
}
char buffer[1024];
DWORD bytes_returned;
while (true) {
if (ReadDirectoryChangesW(
dir_handle, buffer, sizeof(buffer), TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME
| FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_ATTRIBUTES
| FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_LAST_ACCESS
| FILE_NOTIFY_CHANGE_CREATION
| FILE_NOTIFY_CHANGE_SECURITY,
&bytes_returned,
nullptr,
nullptr
)) {
FILE_NOTIFY_INFORMATION *info =
reinterpret_cast<
FILE_NOTIFY_INFORMATION *>(buffer);
std::wcout << "Change detected in: "
<< info->FileName << '\n';
} else {
std::cerr
<< "Failed to read directory changes\n";
}
}
CloseHandle(dir_handle);
}
int main() {
watch_directory(L"c:\\test");
}
Change detected in: newfile.txt
In this example:
CreateFile
opens the directory for monitoring.ReadDirectoryChangesW
watches for changes in the directory and reports them.On Linux, you can use the inotify
API to watch for directory changes. Here’s a basic example using inotify
:
#include <limits.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <iostream>
void watch_directory(const std::string &directory) {
int inotify_fd = inotify_init();
if (inotify_fd < 0) {
std::cerr << "Failed to initialize inotify\n";
return;
}
int watch_fd = inotify_add_watch(
inotify_fd, directory.c_str(),
IN_MODIFY | IN_CREATE | IN_DELETE
);
if (watch_fd < 0) {
std::cerr << "Failed to add watch\n";
close(inotify_fd);
return;
}
char buffer[
sizeof(struct inotify_event) + NAME_MAX + 1];
while (true) {
int length = read(
inotify_fd, buffer, sizeof(buffer));
if (length < 0) {
std::cerr << "Failed to read inotify events\n";
break;
}
struct inotify_event *event = reinterpret_cast<
struct inotify_event *>(buffer);
if (event->len) {
std::cout << "Change detected in: "
<< event->name << '\n';
}
}
inotify_rm_watch(inotify_fd, watch_fd);
close(inotify_fd);
}
int main() {
watch_directory("/tmp/test");
}
Change detected in: newfile.txt
In this example:
inotify_init
initializes the inotify instance.inotify_add_watch
adds a watch on the specified directory.read
retrieves events, and we print the name of the file that changed.These examples show how to watch directories on different platforms. Using a cross-platform library like boost::asio
or libuv
can simplify this process by providing a consistent API across multiple operating systems.
Answers to questions are automatically generated and may not have been reviewed.
Create, delete, move, and navigate through directories and files using the standard library's filesystem
module.