How to monitor a folder with all subfolders and files inside?
From the inotify manpage:
IN_CREATE File/directory created in watched directory (*).
It can be done by catching this event.
Again from the manpage:
Limitations and caveats
Inotify monitoring of directories is not recursive: to monitor subdirectories under a directory, additional watches must be created. This can take a significant
amount time for large directory trees.
So, you will need to do the recursive part yourself. You can start by looking an example from here. You should also have a look at the project notify-tools
EXAMPLE as asked in comments: It monitors /tmp/inotify1
& /tmp/inotify2
for new files created & displays the events
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE ( sizeof (struct inotify_event) )
#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
int main( int argc, char **argv )
{
int length, i = 0;
int fd;
int wd[2];
char buffer[BUF_LEN];
fd = inotify_init();
if ( fd < 0 ) {
perror( "inotify_init" );
}
wd[0] = inotify_add_watch( fd, "/tmp/inotify1", IN_CREATE);
wd[1] = inotify_add_watch (fd, "/tmp/inotify2", IN_CREATE);
while (1){
struct inotify_event *event;
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
event = ( struct inotify_event * ) &buffer[ i ];
if ( event->len ) {
if (event->wd == wd[0]) printf("%s\n", "In /tmp/inotify1: ");
else printf("%s\n", "In /tmp/inotify2: ");
if ( event->mask & IN_CREATE ) {
if ( event->mask & IN_ISDIR ) {
printf( "The directory %s was created.\n", event->name );
}
else {
printf( "The file %s was created.\n", event->name );
}
}
}
}
( void ) inotify_rm_watch( fd, wd[0] );
( void ) inotify_rm_watch( fd, wd[1]);
( void ) close( fd );
exit( 0 );
}
Test run:
shadyabhi@archlinux ~ $ ./a.out
In /tmp/inotify1:
The file abhijeet was created.
In /tmp/inotify2:
The file rastogi was created.
^C
shadyabhi@archlinux ~ $
sub directory and main directory monitoring in java
In short, you have only registered the parent directory to be watched. Any sub-directories you create will not be watched. See here.
How to watch a folder and subfolders for changes
A WatchService
only watches the Path
s you register. It does not go through those paths recursively.
Given /Root
as a registered path
/Root
/Folder1
/Folder2
/Folder3
If there is a change in Folder3
, it won't catch it.
You can register the directory paths recursively yourself with
private void registerRecursive(final Path root) throws IOException {
// register all subfolders
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
return FileVisitResult.CONTINUE;
}
});
}
Now the WatchService
will notify all changes in all subfolders of Path root
, ie. the Path
argument you pass.
How do I (recursively?) monitor contents of new directories using inotify?
Well the fastest to implement (but not the fastest in reality) would be to:
Create the initial tree of directories by recursively exploring the children; An example in C/Linux can be found here:
http://www.lemoda.net/c/recursive-directory/
Add a watch for each subdirectory; When something has been modified or changed you can parse all children recursively and see the differences. Something similar was discussed here:
How to monitor a folder with all subfolders and files inside?If this solution doesn't appeal to you, you might try to do a polling mechanism such that you must re-check the whole structure using a thread at a certain time interval.
Hope it helps!
How to monitor a complete directory tree for changes in Linux?
To my knowledge, there's no other way than recursively setting an inotify
watch on each directory.
That said, you won't run out of file descriptors because inotify
does not have to reserve an fd to watch a file or a directory (its predecessor, dnotify
, did suffer from this limitation). inotify
uses "watch descriptors" instead.
According to the documentation for inotifywatch, the default limit is 8192 watch descriptors, and you can increase it by writing the new value to /proc/sys/fs/inotify/max_user_watches
.
Related Topics
Std::Map Emplace Without Copying Value
What Can and Can't I Specialize in the Std Namespace
Difference Between *(Pointer + Index) and Pointer[]
How to Find and Replace String
Automatically Stop Visual C++ 2008 Build at First Compile Error
Porting Clock_Gettime to Windows
Converting Multidimensional Arrays to Pointers in C++
Invalid Conversion from 'Void*' to 'Char*' When Using Malloc
How to Efficiently Display Opencv Video in Qt
Is Passing a C++ Object into Its Own Constructor Legal
How to Include Header Files in Gcc Search Path
Is There Any Reason to Check for a Null Pointer Before Deleting
Where Is the Lock for a Std::Atomic