CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Question with a simple disk walking script

 



Siei
New User

Apr 30, 2013, 2:42 PM

Post #1 of 6 (722 views)
Question with a simple disk walking script Can't Post


Code
#!/usr/bin/perl -w 

use strict;

use Cwd;




if( scalar @ARGV != 1 )
{
die "Enter a Directory $!\n";

}




my $dir = $ARGV[0];

chdir( $dir );

$dir = getcwd();


my $total_size =0;

my $timemodified =0;

my $filename="";
my $lastname;

if(-e $dir){
($total_size, $timemodified, $filename) = &dirwork( $dir, $total_size, $timemodified, $filename );


}

else {
die "Enter a readable directory $! \n";}

sub dirwork()
{

my $dir = $_[0];

my $cur_total = $_[1];

my $cur_last = $_[2];

my $cur_name = $_[3];


opendir (my $dh, $dir);
my @objs = readdir($dh);


closedir $dh;



@objs = grep(!/^.{1,2}$/, @objs);

foreach my $current (@objs){
my ($total_size, $timemodified, $filename);

# Checks for files and records their info/prints file path

if( -f "$dir/$current" )
{

my @fileinfo = stat($current);
print "$dir/$current is a file, and size = $fileinfo[7] bytes \n";


$cur_total += $fileinfo[7];
my $lastname = "$dir/$current";

$timemodified = $fileinfo[9];

} # End checking for files

# Compares the timemodified with the curr_last to determine if the last file or new one was modified more recently

if( $timemodified > $cur_last )
{

$cur_last = $timemodified;

$cur_name = $lastname;


} #end of compare


# Searches for directories and tries to preform the sub

if( -d "$dir/$current" )
{

my @fileinfo = stat($current);
print "$current is a directory of size $fileinfo[7]...descending \n";
($total_size, $timemodified, $filename) = &dirwork( "$dir/$current", $cur_total, $cur_last, $cur_name );

$cur_total += $total_size;

} #end of directory recursion





}
#End of Loop

return( $cur_total, $cur_last, $cur_name );


} #End of sub

print "$total_size, $timemodified";


It works on the first set of files in a directory just fine and reads out their size. However upon trying to enter a new directory and do those it registers blank sizes. Any help on how to get this up and working as intended would be great!


FishMonger
Veteran / Moderator

Apr 30, 2013, 4:28 PM

Post #2 of 6 (717 views)
Re: [Siei] Question with a simple disk walking script [In reply to] Can't Post

Is this for a class homework assignment?

If not, save yourself time and trouble by using the File::Find module.

http://search.cpan.org/~rjbs/perl-5.16.3/lib/File/Find.pm


Siei
New User

Apr 30, 2013, 5:04 PM

Post #3 of 6 (711 views)
Re: [FishMonger] Question with a simple disk walking script [In reply to] Can't Post

Sadly it is though after reworking it all seems well with this code, except that it will not show a folder as being last modified. Could this be because I am executing the script on windows or?


Code
#!/usr/bin/perl -w 

use strict;

use Cwd;




if( scalar @ARGV != 1 )
{
die "Enter a Directory $!\n";

}




my $dir = $ARGV[0];

chdir( $dir );

$dir = getcwd();


my $total_size =0;

my $timemodified =0;

my $filename="";

if(-e $dir){
($total_size, $timemodified, $filename) = &dirwork( $dir, $total_size, $timemodified, $filename );


}

else {
die "Enter a readable directory $! \n";}

sub dirwork()
{

my $dir = $_[0];

my $cur_total = $_[1];

my $cur_last = $_[2];

my $cur_name = $_[3];


opendir (my $dh, $dir);
my @objs = readdir($dh);


closedir $dh;



@objs = grep(!/^.{1,2}$/, @objs);

foreach my $current (@objs){
my ($total_size, $timemodified, $filename);

# Checks for files and records their info/prints file path

if( -f "$dir/$current" )
{

my @fileinfo = stat("$dir/$current");
print "$dir/$current is a file, and size = $fileinfo[7] bytes \n";


$cur_total += $fileinfo[7];
$filename = "$dir/$current";

$timemodified = $fileinfo[9];

} # End checking for files


# Searches for directories and tries to preform the sub



if( -d "$dir/$current" )
{

my @fileinfo = stat("$dir/$current");
print "$dir/$current is a directory, and the size is $fileinfo[7] \n";
$timemodified = $fileinfo[9];


my $dir = $current;

chdir( $dir );

$dir = getcwd();

($total_size, $timemodified, $filename) = &dirwork( $dir, $cur_total, $cur_last, $cur_name );

$cur_total = $total_size;

}



# Compares the timemodified with the curr_last to determine if the last file or new one was modified more recently

if( $timemodified > $cur_last )
{

$cur_last = $timemodified;

$cur_name = $filename;


} #end of compare



}
#End of Loop

return( $cur_total, $cur_last, $cur_name );


} #End of sub

print "$total_size, $timemodified, $filename ";



Laurent_R
Veteran / Moderator

May 1, 2013, 2:06 AM

Post #4 of 6 (698 views)
Re: [Siei] Question with a simple disk walking script [In reply to] Can't Post

I just quickly tried stat on some Windows folders (but running Perl under Cygwin), the mtime field (field 9) of stat seems to return the right information. Some of my folders are correctly reported to be about 4 ou 5 years old.

I do not know if it is the same on a pure Windows install of Perl such as Active State.


BillKSmith
Veteran

May 1, 2013, 5:23 AM

Post #5 of 6 (692 views)
Re: [Siei] Question with a simple disk walking script [In reply to] Can't Post

I recommend that you test for the success of opendir and report failures. The symptoms that you describe are consistent with its failure.

Code
opendir (my $dh, $dir) or die "Cannot open $dir:$!";


There are several other minor problems:

  • You must escape the dot in your test for special directories.

    Code
    @objs = grep(!/^\.{1,2}$/, @objs);



  • You should not be using prototypes in your subroutine. They do not do what you think! In fact, you have them specified wrong.

    Code
    sub dirwork



  • You should not be using the "&" in your subroutine calls. The biggest thing it does is hide the previous problem.

    Code
    ($total_size, $timemodified, $filename) 
    = dirwork( $dir, $total_size, $timemodified, $filename );



  • UPDATE:
    Added corrected code.
    Removed erroneous comment
    Good Luck,
    Bill

    (This post was edited by BillKSmith on May 1, 2013, 10:08 AM)


    Chris Charley
    User

    May 1, 2013, 12:30 PM

    Post #6 of 6 (677 views)
    Re: [Siei] Question with a simple disk walking script [In reply to] Can't Post


    Quote
    Sadly it is though after reworking it all seems well with this code, except that it will not show a folder as being last modified. Could this be because I am executing the script on windows or?

    When I run stat on a directory in Windows, it reports mtime, (stat $dir)[9] but doesn't have a size (stat $dir)[7].

     
     


    Search for (options) Powered by Gossamer Forum v.1.2.0

    Web Applications & Managed Hosting Powered by Gossamer Threads
    Visit our Mailing List Archives