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

T

Thibaut Barrère

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
 
J

John Pritchard-williams

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
 
M

Michael Morin

Thibaut said:
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

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
http://ruby.about.com/
Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company
 
R

Robert Klemme

2008/8/29 Michael Morin said:
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

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. ;-) Sorry
for being silly today.

Kind regards

robert
 
M

Michael Morin

Robert said:
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 :p

--
Michael Morin
Guide to Ruby
http://ruby.about.com/
Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company
 
A

ara.t.howard

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=E8re / LoGeek



here is an ancient ruby script i use for that, it also considers =20
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 =3D false

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


units =3D [
[: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 =3D sum / size.to_f
printf " %s: %.3f\n", label, q if q >=3D 1
end

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

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



a @ http://codeforpeople.com/
 
R

Robert Klemme

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 :p

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

Have a nice weekend!

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top