Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

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 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 "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
Replies are listed 'Best First'.
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.

      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 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 ... }
      Wow! Thank you very much!!!
Re: Dir size
by GrandFather (Sage) on Mar 05, 2009 at 22:57 UTC
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 Discipulus (Vicar) 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?

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (6)
As of 2015-11-25 14:26 GMT
Find Nodes?
    Voting Booth?

    What would be the most significant thing to happen if a rope (or wire) tied the Earth and the Moon together?

    Results (677 votes), past polls