Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Dir size

by larus (Acolyte)
on Mar 05, 2009 at 19:45 UTC ( #748644=perlquestion: print w/ replies, xml ) Need Help??
larus has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to print out all the directories and their sizes using the script below but I'm not getting correct results (I got some advice from http://www.mail-archive.com/beginners@perl.org/msg99758.html). For example it says that my C:/Perl/etc directory is 15.32 mb but Win Explorer folder properties says that it's 372 kb. I'm using Win XP and the script like this
C:\Perl\>perl Print_dirs.pl "C:/Perl/"
Where is the error, can you help me?
#!/bin/perl use warnings; use strict; use File::Find; my $path = $ARGV[0]; die "You must supply a full directory path" unless (-e $path && -d $pa +th); opendir (DIR, $path) or die "can't opendir $path: $!"; my @directories = grep { -d "$path/$_" && ! /^\./ } readdir(DIR); my $total_size_of_files_in_dir; foreach my $dir (@directories) { find(\&wanted, "$path/$dir"); ### Not sure how that worked a +s you called it $directory print "The total size of the file in $dir is " . sprintf("%.2f + Kb", ($total_size_of_files_in_dir * 0.0009765625)) . "\n"; print "The total size of the file in $dir is " . sprintf("%.2f + Mb", ($total_size_of_files_in_dir * 9.5367431641e-7)) . "\n"; print "The total size of the file in $dir is " . sprintf("%.2f + Mb", (&size_in_mb($total_size_of_files_in_dir))) . "\n"; } sub wanted { if (-f $_) { $total_size_of_files_in_dir += -s; } } sub size_in_mb { my $size_in_bytes = shift; return $size_in_bytes / (1024 * 1024); }

Comment on Dir size
Select or Download Code
Re: Dir size
by shmem (Canon) on Mar 05, 2009 at 20:07 UTC

    Looks like your $total_size_of_files_in_dir is accumulating. Reset it at the end of the for loop.

      Wow! Thank you very much!!!
      Better yet, avoid the global entirely.
      #!/usr/bin/perl use strict; use warnings; use File::Find qw( find ); my ($path) = @ARGV or die("usage: perl dir_size.pl dirpath\n"); opendir(my $dh, $path) or die("Can't open dir $path: $!\n"); while (defined(my $dir = readdir($dh)) { next if $dir =~ /^\./; my $full_dir = "$path/$subdir"; next if ! -d $full_dir; my $total = 0; find(sub { $total += -s if -f $_ }, $full_dir); print "The total size of the files in $dir is " . sprintf("%.2f Kb", ($total/1024)) . "\n"; print "The total size of the files in $dir is " . sprintf("%.2f Mb", ($total/(1024*1024))) . "\n"; }

      I don't know why people use a named sub for find. If I did want to split out the logic into a separate sub, I'd do something like

      sub some_sub { my @results; find(sub { push @results, $_ if check($_) }); ... } sub check { ... Check if the file matches. Doesn't know about File::Find ... }
Re: Dir size
by Tanktalus (Canon) on Mar 05, 2009 at 21:52 UTC
Re: Dir size
by satanicpuppy (Novice) on Mar 05, 2009 at 22:56 UTC
    You can try using Win32::File instead of File::Find, for starters. Otherwise, windows being windows, if you want to know what size IT thinks a directory is, might as well ask it:
    $temp = `Dir $your_directory_here`; if($temp =~ m/(\s+)(\d+)( File)(\S{3})(\s+)(\S+)( bytes)/i){ print "$6 bytes\n"; }
    That's some ugly code. Works though, least in XP. YMMV, and it won't give you sizes on subdirectories. The regex is a bit more brittle than I'd like...It'd be cleaner if you ripped all the /'s and ,'s out of the directory output first. Then you'd probably be safe just doing:
    ... if($temp =~ m/(\s+)(\d+)( bytes)/i){ ...
      if you use "Dir /-C" it'll drop the commas.
Re: Dir size
by GrandFather (Cardinal) on Mar 05, 2009 at 22:57 UTC
Re: Dir size
by Discipulus (Curate) on Mar 06, 2009 at 08:56 UTC
    search first my friend! I have found this How do I recursively process files through directories, one of my first (newbiest's) contribution..

    if you are in a win32 env i found that the following code is very much faster:
    sub get_dir_size { my $root = shift; return 'NOT EXISITING FOLDER' unless -e $root; my $fs = Win32::OLE->CreateObject('Scripting.FileSystemObject'); my $folder = $fs->GetFolder($root); my $dimensione = $folder->size(); $fs = undef; return $dimensione; }
    HtH Lor*

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://748644]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2014-11-23 16:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (134 votes), past polls