RockE has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks I would like to replace the code in a script of mine (between the lines of #######) using file::find however I am finding all examples of how to actually use it non friendly. Any help would be appreciated.

#!/usr/bin/perl use strict; use warnings; package isomake; our $package = 'ISOMake'; our $version = '0.5'; use Fcntl; #Die if no parameters are given to the program @ARGV or die "$package: no parameters given, usage - perl isomake.pl P +12345678 \n"; #Checking for valid file name our $P00=shift; chomp $P00; $P00 =~qr{^[LMP]\d{8}$} or die "$package: $P00 is not a valid Media Id +entifier\n"; #************************************************** my $path = "C:\\Temp\\"; my $drive = "C:\\Temp\\"; my @badlist=(); my @dirlist = (); my @sfiles = (); my $nbad = 0; my $problem = 0; my $ndir = 0; my $ssize = 0; #Open a file to list any bad files found open (BADLIST, ">$path/badfilelist.csv") or die "$! error trying to ov +erwrite"; print BADLIST "****BAD FILE LISTING****\n"; #Read each item on the drive and check it print "**********Contents of the media on drive $drive**********\n"; $dirlist[0] = $drive; chdir $drive; FILE: foreach my $file (@dirlist) { if ($file =~ qr{^\.\.*$}) {next FILE}; + # Ignore directory references if ($file =~ qr{^Thumbs\.db}) {next FILE}; + # Ignore Thumbs.db files if ($file =~ qr{^Desktop\.ini}) {next FILE}; + # Ignore Desktop.ini files if ($file =~ qr{^AutoRun\.inf}) {next FILE}; + # Ignore AutoRun.inf files if (not -e $file) { print "$file does not seem to exist\n"; $problem++; next FILE; } if (-d $file) { my $DDIR = undef; if (not opendir($DDIR,$file)) { + # Open the directory print "Could not open Directory $file, Error: $!\n"; $problem++; next FILE; } my @ddir = readdir $DDIR; + # Find out what is there close $DDIR; DIR: foreach my $dfile (@ddir) { + # And add it to the list if ($dfile =~ qr{^\.\.*$}) {next DIR;}; my $fullpath = $file . $dfile; if (-d $fullpath) { $fullpath .= '\\'; push @dirlist,$fullpath; print "Directory: $fullpath\n"; $ndir++; next DIR; } push @dirlist,$fullpath; } next FILE; } my $FILE = undef; my $x = ''; my $rsize = 0; if (not open($FILE,'<',$file)) { print "Could not open $file, Error: $!\n"; $problem++; next DIR; } while (my $bytes = sysread($FILE,$x,32768,O_BINARY)) { if (not defined $bytes) { print "Error Reading File $file: $!\n"; $problem++; } $rsize += $bytes; } close $FILE; my $fsize = (stat($file))[7]; + # How big is it? if (not($fsize == $rsize)) { print "Byte Check Error in $file, Counted $rsize bytes, expect +ed $fsize bytes\n"; $problem++; } $ssize += $fsize; push @sfiles,$file; print "File: $file, size = $fsize\n"; if ($problem) { print "File $file is ***NOT*** ok, found $problem problems :( +\n"; push @badlist, '$file'; $nbad++; } } my $nfiles = @sfiles; print "\nFound $ndir directories on $drive\n"; print "Found $nfiles files on $drive total size is $ssize bytes\n"; #Write to badfilelist.csv with filenames of bad files foreach my $badfile (@badlist) { print BADLIST "$badfile\n"; } print BADLIST "\n$nbad possible bad files"; close BADLIST; print "Found $nbad bad file/s on $drive\n"; #************************************************** $problem and die "$problem problems found in $drive\n"; #Write out file listing open (FILELIST, ">$path/filelist.txt") or die "$! error trying to over +write"; foreach my $listing (@dirlist) { print FILELIST "$listing\n"; } close FILELIST;

Replies are listed 'Best First'.
Re: File::Find Question
by jkeenan1 (Deacon) on Oct 31, 2013 at 01:51 UTC
    Your code is in severe need of simplification and cleanup before we can consider whether using File::Find would improve it.

    For example, write off the bat I detected three variables which are declared but never used:

    $size $name $SDIR
    Get rid of them -- and while you're removing them, also delete all the commented-out code, which only serves as a distraction to those reading your post and trying to help you.

    Next, note that on line 56 you assign $drive to $dirlist[0], and then within five lines you call for a loop over the contents of @dirlist. If you only have one entry in the list over which you are iterating, you can ditch the for loop as well.

    Thank you very much.

    Jim Keenan

      Thanks for your reply Jim I've cleaned it up as requested. $drive is usually a CD drive, there is always more than one file

Re: File::Find Question
by toolic (Bishop) on Oct 30, 2013 at 23:44 UTC

      Thanks, seen this already and the examples didn't help me...