in reply to Re^3: fast count files
in thread fast count files

Thanks for that quick reply But I have 2 use my @files = `attrib /s c:\\*`; my $n = scalar @files; as without it says that wc is an unrecognised command .Also the I am showing the code of the fastest method I know

use strict; my $f; # number of files my $d; # number of dirs sub count_files { my ($ref) = @_; foreach my $dir (@$ref) { $dir = readlink $dir and chop $dir if -l $dir; # read link next unless opendir(my $dir_h, $dir); # open dir o ++r next my @dirs; while (defined(my $file = readdir $dir_h)) { if ($file eq '.' or $file eq '..') { next; } if (-d "$dir/$file") { ++$d; # counting d +irs push @dirs, "$dir/$file"; } elsif(-f _) { ++$f; # counting f +iles } } closedir $dir_h; count_files(\@dirs); } [$f, $d]; } foreach my $arg (@ARGV) { my @dir = -d $arg ? $arg : next; ($f, $d) = (0, 0); print "$arg\nFiles\t: $$_[0]\nFolders\t: $$_[1]\n" for count_files +(\@ dir); }

suggest a faster method and also how to run without using my @files = `attrib /s c:\\*`; my $n = scalar @files;

Replies are listed 'Best First'.
Re^5: fast count files
by BrowserUk (Pope) on Jan 06, 2012 at 12:19 UTC
    But I have 2 use my @files = `attrib /s c:\\*`; my $n = scalar @files;

    I did warn you against loading the entire list into perl. It really slows things down.

    as without it says that wc is an unrecognised command

    There are various cures for that possible:

    • Download yourself a copy of wc.exe for Windows.

      It is easy to find and its a program that is just to useful to be without.

    • Use attrib /s c:\* | perl -nE"}{say $."

      It is a poor substitute but works for this use.

    • Use the suggestion by cdarke.

      Simple and effective.

    But I remembered a faster method. This uses the Windows Script Host to do the donkey work via Win32::OLE and runs 3 times faster on my machine.

    2:14 instead of 6:40 on my machine. It also counts the directries as it goes which may or may not be useful to you:

    #! perl -slw use strict; use Time::HiRes qw[ time ]; use Win32::OLE qw[in]; my $start = time; my $fso = Win32::OLE->new( 'Scripting.FileSystemObject' ); my @folders = $fso->GetFolder( $ARGV[0] ); my $cFolders = 0; my $cFiles = 0; while( @folders ) { local $^W; my $folder = pop @folders; $cFiles += $folder->Files->Count; $cFolders += $folder->Subfolders->Count; for my $subFolder ( in $folder->SubFolders ) { $cFiles += $subFolder->Files->Count; $cFolders += $subFolder->SubFolders->Count; push @folders, $_ for in $subFolder->SubFolders ; } } my $seconds = time - $start; my $minutes = int( $seconds / 60 ); $seconds %= 60; printf "Folders:$cFolders Files:$cFiles [%u:%.2f]\n", $minutes, $seconds; __END__ [12:05:12.81] c:\test>countFiles c:\ Folders:68860 Files:1234105 [2:14.00]

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      thanks guys I tried with win32::Ole , File::Find and word count(linux one see above thread)method .Win32::Ole and wc give almost the same time .. So is there a way to count even faster that that??

Re^5: fast count files
by marto (Cardinal) on Jan 06, 2012 at 11:36 UTC