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

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

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

2008/8/29 Michael M. [email protected]:

puts size
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

Thibaut Barrère wrote:

File.size(name)

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

Robert K. wrote:

And it even “fits” nicely on one line

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

2008/8/29 Michael M. [email protected]:

Robert K. 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.

Thanks guys,

Find seems like a good fit for this one!

cheers,

– T

Robert K. wrote:

2008/8/29 Michael M. [email protected]:

Robert K. 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:

On 29.08.2008 16:29, Michael M. 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:

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

Have a nice weekend!

robert

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

File.size(name)
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

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/