in reply to Problem unlinking files

Just to add to the information. What i want actaually is a refreshing of the directory while its undergoing the 'readdir while loop', if some deletion of files happens in this while loop.

Replies are listed 'Best First'.
Re^2: Problem unlinking files
by jrsimmon (Hermit) on Nov 16, 2007 at 15:18 UTC
    Without seeing your code, this is just a guess...

    I assume that now you are doing something like this:
    opendir(DIR, "$somedir") or die $!; while(my $dirEntry = readdir(DIR)){ if(&SOME_TEST($dirEntry)){ unlink $dirEntry; unlink $dirEntryPair; } } closedir(DIR);


    If in fact this is what you're doing, why don't you try another approach:
    opendir(DIR, "$somedir") or die $!; my @dir = readdir(DIR); foreach my $dirEntry (@dir){ if(&SOME_TEST($dirEntry)){ unlink $dirEntry; unlink $dirEntryPair; @dir = readdir(DIR); } } closedir(DIR);
      Regarding this part of your suggested code:
      foreach my $dirEntry (@dir){ if(&SOME_TEST($dirEntry)){ ... @dir = readdir(DIR); } }
      As a rule, it is a Bad Idea™ to alter or replace the contents of an array within a "for" loop that is iterating over that array. Results of doing so may be "unpredictable" at best.

      As it turns out, checking for existence of a file before doing "unlink" is actually unnecessary -- you are not checking the return status from "unlink", and frankly, why care whether you "unlink" a file that is non-existent? That sort of "error" is harmless and could safely be ignored.

        Regarding altering the contents of an array while iterating over it...point taken...that was a bad suggestion.

        Regarding the file existence test...the poster didn't really indicate what kind of test was being performed. Since no code was provided, I think we can only assume that he/she has reasons for performing the test and possibly deleting the file based off the results.
      Say, why do you have the ampersand before 'SOME_TEST' -- &SOME_TEST(...) -- but not anywhere else? Followup: why have an ampersand at all (in your proposed code)?
        I always use an ampersand as part of function calls. I understand that some people consider this to be unnecessary...but I disagree.
Re^2: Problem unlinking files
by graff (Chancellor) on Nov 17, 2007 at 04:00 UTC
    Just to add to the information. What i want actaually is a refreshing of the directory while its undergoing the 'readdir while loop', if some deletion of files happens in this while loop.

    Why do you want to "refresh" the directory (and what do you mean by that, anyway)? It would have been better if you had added a sample of the code you have tried.

    Maybe rather than deleting files within the loop, you might want to just build a list of files to be deleted (store the file names as keys in a hash), and then delete them as a separate step:

    opendir(DIR,$somepath); my %todelete; while( $file = grep /[^.]/, readdir DIR ) { if ( !exists( $todelete{$file} ) and some_test( "$somepath/$file" +)) { $todelete{$file} = undef; ( my $otherfile = $file ) =~ s/this/that/; $todelete{$otherfile} = undef; } } unlink "$somepath/$_" for ( keys %todelete );