Search code examples
perlfilemonitor

can i use wild card to monitor particular files in a directory in File::Monitor?


I am using File::Monitor perl module to notify me about the new/modified files.

Below code snippet is only working for 1.txt input file! where as i would like to monitor for for all the input files.

I have 2 questions

 1-> Does it support wild card such as *.txt?
 2-> Does it monitor recursively ?

Here's the code snippet.

#!/usr/bin/perl
use strict;
use warnings;
use File::Monitor;
use File::Monitor::Object;

my @Files=("1.txt","2.txt"); 
my $dir = "C:\\Users\\goudarsh\\Desktop\\Perl_test_scripts";

my $wFileMonitor = File::Monitor->new();
foreach my $wFile (@Files){
my $file = "$dir\\$wFile";
$wFileMonitor->watch($file);
#-- First scan does nothing
$wFileMonitor->scan;

while (1){
  my @changes = $wFileMonitor->scan;
foreach my $object (@changes) {
my $modified = $object->mtime;
  print "$wFile changed\n";
  #fcopy ("$wFile","c:\\newpath");
}
}
}

Solution

  • reading directory is ok! but a folder is created within this input directory and then if any *.txt file is created then ? i want to observed all .txt file inside my input directory

    There's a recurse option you can set for a directory, which will watch for changes in all subdirectories:

    $monitor->watch( {
        name        => '/Users/7stud/pperl_programs/test_dir/',
        recurse     => 1,
        callback    => {files_created => \&textfile_notifier},  #event => handler
    } );
    

    Here's a way to track creation of .txt files:

    use strict;
    use warnings;
    use 5.020;
    
    use File::Monitor;
    use File::Basename;
    
    sub textfile_notifier {
        my ($watch_name, $event, $change) = @_; 
    
        my @new_file_paths = $change->files_created; #The change object has a property called files_created, 
                                                     #which contains the names of any new files
        for my $path (@new_file_paths) {
            my ($base, $fname, $ext) = fileparse($path, '.txt'); # $ext is "" if the '.txt' extension is
                                                                 # not found, otherwise it's '.txt'.
            if ($ext eq '.txt') {
                say "$path was created";
            }
        }
    }
    
    my $monitor = File::Monitor->new();
    
    $monitor->watch( {
        name        => '/Users/7stud/pperl_programs/test_dir/',
        recurse     => 1,
        callback    => {files_created => \&textfile_notifier},  #event => handler
    } );
    
    $monitor->scan;
    
    while (1) {
        $monitor->scan;
        sleep(2);
    }
    

    Listen for modifications to all existing files in a directory; also listen for created files in the directory, and listen for subsequent modifications to the created files:

    use strict;
    use warnings;
    use 5.020;
    
    use File::Monitor;
    use File::Basename;
    use File::Find;
    
    #Gather all existing .txt files:
    
    my @existing_textfiles;
    
    sub textfiles {
         my ($base, $fname, $ext) = fileparse($File::Find::name, '.txt');
    
         if ($ext eq '.txt') {
             push @existing_textfiles, $File::Find::name;
         }
    }
    
    find(\&textfiles, '/Users/7stud/pperl_programs/test_dir/');
    #------------------------------
    
    #Watch for modifications to existing text files:
    
    my $monitor = File::Monitor->new();
    
    for my $existing_textfile (@existing_textfiles) {
    
        $monitor -> watch( {
                name        => $existing_textfile,
                callback    => { mtime => \&textfile_modified },
        } );
    
    }
    
    sub textfile_modified {
        my ($modified_file) = @_; 
        say "modified: $modified_file";
    }
    #------------------------------
    
    #Watch for created text files:
    
    $monitor->watch( {
        name        => '/Users/7stud/pperl_programs/test_dir/',
        recurse     => 1,
        callback    => {files_created => \&textfile_created},  
    } );
    
    sub textfile_created {
        my ($watch_dir, $event, $change) = @_;
    
        my @new_files = $change->files_created;
    
        for my $new_file (@new_files) {
            my ($base, $fname, $ext) = fileparse($new_file, '.txt');
    
            if ($ext eq '.txt') {
                say "created: $new_file";
    
                #Watch for moditications to created text files:
                $monitor->watch( {
                        name        => $new_file,
                        callback    => { mtime => \&textfile_modified },
                } );
                #------------------------
            }
        }
    }
    #---------------------------
    
    $monitor->scan;
    
    while (1) {
        $monitor->scan;
        sleep(2);
    }
    

    Note that deleting a file will show up as a modified file.