Computing folder size - do you have something cleaner than this?

Hi guys,

I'm computing an approximate folder size by summing the sizes of its
files, recursively, with the following code:

def item_size(name)
  if File.directory?(name)
    (Dir.entries(name) - ['.','..']).inject(0) { |sum,file| sum +
item_size(File.join(name,file)) }
  else
    File.size(name)
  end
end

Another version would be:

def item_size_2(name)
  Dir[name+'/**/*'].inject(0) { |sum,file| sum + (File.directory?
(file) ? 0 : File.size(file)) }
end

can anyone think of a shorter or more readable way of writing it ? Do
you know a library that would do this ?

cheers,

Thibaut Barrère / LoGeek

···

--
http://blog.logeek.fr - learning content for developers
http://evolvingworker.com - tools for a better day

Hi Thibaut,

Don't know about more readable faster, but there is a built-in 'find'
library which you might want to try, something like:

require 'find'
...
def sizer(dirname)
   size=0
   Find.find(dirname) { |f| size=+File.size(f); }
   size
end

Cheers

John

···

--
Posted via http://www.ruby-forum.com/.

Hi friend,

ruby core Find class may be more appropriate. But you may run
benchmark to see if it runs faster.

http://ruby-doc.org/core/classes/Find.html

HTH.

Antonin

Thibaut Barrère wrote:

Hi guys,

I'm computing an approximate folder size by summing the sizes of its
files, recursively, with the following code:

def item_size(name)
  if File.directory?(name)
    (Dir.entries(name) - ['.','..']).inject(0) { |sum,file| sum +
item_size(File.join(name,file)) }
  else
    File.size(name)
  end
end

Another version would be:

def item_size_2(name)
  Dir[name+'/**/*'].inject(0) { |sum,file| sum + (File.directory?
(file) ? 0 : File.size(file)) }
end

can anyone think of a shorter or more readable way of writing it ? Do
you know a library that would do this ?

cheers,

Thibaut Barrère / LoGeek
--
http://blog.logeek.fr - learning content for developers
http://evolvingworker.com - tools for a better day

Maybe use the Find module?

#!/usr/bin/env ruby
require 'find'

size = 0
Find.find(".") do|f|
   size += File.size(f) if File.file?(f)
end

puts size

···

--
Michael Morin
Guide to Ruby

Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company

here is an ancient ruby script i use for that, it also considers gzip'd files uncompressed but you could comment that out:

cfp:~ > dirsum src/ruby
src/ruby:
   b: 768067279.000
   kb: 750065.702
   mb: 732.486

cfp:~ > cat bin/dirsum
#! /usr/bin/env ruby

at_least_one = false

ARGV.each do |dir|
   begin
     sum = 0
     Dir["#{ dir }/**/**"].each do |path|
       if test ?f, path
         p path if $DEBUG
         begin
           case path
             when /\.(?:gz|z)\s*$/io
               cmd = "{ gzip -l #{ path } | tail -1 | awk '{print $2}' ;} 2>/dev/null"
               out = `#{ cmd }`
               raise unless $?.exitstatus == 0
               sum += out.to_i
             else
               sum += File.stat(path).size
           end
         rescue
           warn "failed to sum <#{ path }>"
         end
       end
     end

     units = [
       [:b , (2 ** 0)],
       [:kb , (2 ** 10)],
       [:mb , (2 ** 20)],
       [:gb , (2 ** 30)],
       [:tb , (2 ** 40)],
       [:pb , (2 ** 50)],
     ]

     puts "#{ dir }:"
     units.each do |(label, size)|
       q = sum / size.to_f
       printf " %s: %.3f\n", label, q if q >= 1
     end

     at_least_one = true
   rescue => e
     warn "failed to sum <#{ dir }>"
     next
   end
end

abort "#{ $0 } dir [dir]+" unless at_least_one

a @ http://codeforpeople.com/

···

On Aug 29, 2008, at 4:56 AM, Thibaut Barrère wrote:

Hi guys,

I'm computing an approximate folder size by summing the sizes of its
files, recursively, with the following code:

def item_size(name)
if File.directory?(name)
   (Dir.entries(name) - ['.','..']).inject(0) { |sum,file| sum +
item_size(File.join(name,file)) }
else
   File.size(name)
end
end

Another version would be:

def item_size_2(name)
Dir[name+'/**/*'].inject(0) { |sum,file| sum + (File.directory?
(file) ? 0 : File.size(file)) }
end

can anyone think of a shorter or more readable way of writing it ? Do
you know a library that would do this ?

cheers,

Thibaut Barrère / LoGeek
--
http://blog.logeek.fr - learning content for developers
http://evolvingworker.com - tools for a better day

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

And it even "fits" nicely on one line

14:26:51 ~$ ruby -r find -r enumerator -e 'p
Find.to_enum(:find,"lib").inject(0){|s,f|File.file?(f)?s+File.size(f):s}'
42901
14:27:01 ~$ ruby19 -r find -e 'p
Find.to_enum(:find,"lib").inject(0){|s,f|File.file?(f)?s+File.size(f):s}'
42901

Well, if your terminal has at least 108 or so characters. :wink: Sorry
for being silly today.

Kind regards

robert

···

2008/8/29 Michael Morin <uzimonkey@gmail.com>:

Maybe use the Find module?

#!/usr/bin/env ruby
require 'find'

size = 0
Find.find(".") do|f|
size += File.size(f) if File.file?(f)
end

puts size

--
use.inject do |as, often| as.you_can - without end

Thanks guys,

Find seems like a good fit for this one!

cheers,

-- T

Robert Klemme wrote:

And it even "fits" nicely on one line

Not really... Ruby is not Perl, use your enter key.

···

--
Michael Morin
Guide to Ruby

Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company

Well... Smiley is not Serious, use your glasses.

···

2008/8/29 Michael Morin <uzimonkey@gmail.com>:

Robert Klemme wrote:

And it even "fits" nicely on one line

Not really... Ruby is not Perl, use your enter key.

--
use.inject do |as, often| as.you_can - without end

Robert Klemme wrote:

···

2008/8/29 Michael Morin <uzimonkey@gmail.com>:

Robert Klemme wrote:

And it even "fits" nicely on one line

Not really... Ruby is not Perl, use your enter key.

Well... Smiley is not Serious, use your glasses.

Sorry, my eyes glazed over at the first sight of the symbol soup and I didn't even see your last paragraph there. But still... that's painful to look at :stuck_out_tongue:

--
Michael Morin
Guide to Ruby

Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company

Granted, looking at this is hard. But you should see my fingers after typing this. :slight_smile:

Have a nice weekend!

  robert

···

On 29.08.2008 16:29, Michael Morin wrote:

Sorry, my eyes glazed over at the first sight of the symbol soup and I didn't even see your last paragraph there. But still... that's painful to look at :stuck_out_tongue: