How do I make my program watch for file modification in C++?
There are several ways to do this depending on the platform. I would choose from the following choices:
Cross Platform
Trolltech's Qt has an object called QFileSystemWatcher which allows you to monitor files and directories. I'm sure there are other cross platform frameworks that give you this sort of capability too, but this one works fairly well in my experience.
Windows (Win32)
There is a Win32 api called FindFirstChangeNotification which does the job. There is a nice article which a small wrapper class for the api called How to get a notification if change occurs in a specified directory which will get you started.
Windows (.NET Framework)
If you are ok using C++/CLI with the .NET Framework then
System.IO.FileSystemWatcher is your class of choice. Microsoft has a nice article on
how to monitor file system changes using this class.
OS X
The FSEvents API is new for OS X 10.5 and very full-featured.
Linux
Use inotify as Alex mentioned in his answer.
How do I Monitor Text File Changes with C++? Difficulty: No .NET
You can monitor a directory with FindFirstChangeNotification works on any windows.
It's efficent if you know where the file is - otherwise you can use the virtual driver/Filemon described below to check for changes anywhere on the system.
Example code here
Notification when a file changes?
That would be System.IO.FileSystemWatcher.
monitoring file changes c++ linux
When you use inotify, you do not require to poll for all files to check if there are changes. You get a callback system that notifies you when a watched file or directory got changed.
The kernel/filesystem already has this information, so the resource/CPU usage is not just moved to another application, it is actually reduced.
Monitor file system activity with inotify provides more details why to use inotify, shows its basic usage and helps you set it up.
How to stop the repetition of inotify result?
Some remarks:
- You should not "break" as you go out of the inside "while" loop and call read() again
- The IN_MODIFY event does not fill the event->name field (i.e. event->len = 0)
- The number of IN_MODIFY events depends on how you modify the files ("echo xxx >> file" = write only = 1 IN_MODIFY; "echo xxx > file" = truncate + write = 2 IN_MODIFY)
Here is a proposition for your program (with additional prints):
#include <stdio.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <stdlib.h>
#define EVENT_BUF_LEN 4096
#define EVENT_SIZE sizeof(struct inotify_event)
typedef struct{
int length, fd, wd1, wd2;
char buffer[EVENT_BUF_LEN] __attribute__ ((aligned(__alignof__(struct inotify_event))));
} notification;
notification inotify;
int getNotified(char *pathname1, char *pathname2){
inotify.fd = inotify_init();
inotify.wd1 = inotify_add_watch(inotify.fd, pathname1, IN_MODIFY);
printf("wd1 = %d\n", inotify.wd1);
inotify.wd2 = inotify_add_watch(inotify.fd, pathname2, IN_MODIFY);
printf("wd2 = %d\n", inotify.wd2);
while(1){
inotify.length = read(inotify.fd, inotify.buffer, EVENT_BUF_LEN);
int i = 0;
printf("read() = %d\n", inotify.length);
while(i < inotify.length){
struct inotify_event *event = (struct inotify_event *)&inotify.buffer[i];
printf("event->len = %u\n", event->len);
if(event->mask & IN_MODIFY){
if(event->wd == inotify.wd1){
printf("Pathname1 is modified\n");
} else if (event->wd == inotify.wd2){
printf("Pathname2 is modified\n");
}
}
i += (EVENT_SIZE + event->len);
printf("i=%d\n", i);
}
}
inotify_rm_watch(inotify.fd, inotify.wd1);
inotify_rm_watch(inotify.fd, inotify.wd2);
close(inotify.fd);
exit(0);
}
int main(void)
{
getNotified("/tmp/foo", "/tmp/bar");
return 0;
} // main
Here is an example of execution:
$ gcc notif.c -o notif
$ > /tmp/foo
$ > /tmp/bar
$ ./notif
wd1 = 1
wd2 = 2
====== Upon "> /tmp/foo": 1 event (truncate operation)
read() = 16
event->len = 0
Pathname1 is modified
i=16
====== Upon "echo qwerty > /tmp/foo": 2 events (write operation, one event for truncate operation and one for the write of "qwerty" at the beginning of the file)
read() = 16
event->len = 0
Pathname1 is modified
i=16
read() = 16
event->len = 0
Pathname1 is modified
i=16
====== Upon "echo qwerty >> /tmp/foo": 1 event (write of "qwerty" at the end of the file)
read() = 16
event->len = 0
Pathname1 is modified
i=16
Read file changes since the last check without running program constantly in C#
Have a look at the USN Journal for NTFS.
It basically logs all changes to files on an NTFS disk.
Here are some links which might prove useful:
- Creating, Modifying, and Deleting a Change Journal
- Fsutil usn
- File Path from USN Journal
Related Topics
Incrementing in C++ - When to Use X++ or ++X
Reason to Pass a Pointer by Reference in C++
How to Call a Base Class'S Virtual Function If I'M Overriding It
Is Pass-By-Value a Reasonable Default in C++11
Serializing a Class Which Contains a Std::String
What Is the Meaning of the Term "Free Function" in C++
How to Explicitly Instantiate a Template Function
How Do C++ Class Members Get Initialized If I Don't Do It Explicitly
How Does This "Size of Array" Template Function Work
How to Compile For Windows on Linux With Gcc/G++
Does It Make Any Sense to Use Inline Keyword With Templates
Why Must the Copy Assignment Operator Return a Reference/Const Reference
Why Are Arrays of References Illegal
_File_, _Line_, and _Function_ Usage in C++
Difference Between These (Bcondition == Null) and (Null==Bcondition)
What Do 1.#Inf00, -1.#Ind00 and -1.#Ind Mean
How to Succinctly, Portably, and Thoroughly Seed the Mt19937 Prng