Is there a ruby way to get the disk size of a directory?


#1

I was wondering if there was something to du -h?

Juan


#2

Juan Z. wrote:

I was wondering if there was something to du -h?

Juan

Hi Zanos,

Code:

puts files = cd,dir /s

Output:

C:\raveendran\File_concept
Volume in drive C has no label.
Volume Serial Number is F40B-0762

Directory of C:\raveendran\File_concept

12/26/2008 05:14 PM .
12/26/2008 05:14 PM …
05/12/2008 10:43 AM 211 filerite.rb
03/30/2009 09:37 AM 298 filesize.rb
12/22/2008 05:57 PM 239 file_last_line.rb
07/17/2008 12:12 PM 139 findfile.rb
08/08/2008 12:44 PM 225 folder.rb
5 File(s) 1,112 bytes

 Total Files Listed:
           5 File(s)          1,112 bytes
           2 Dir(s)   9,278,435,328 bytes free

Let me know you expecting this or not ?

Regards,
P.Raveendran


#3

On 29.03.2009 21:58, Juan Z. wrote:

I was wondering if there was something to du -h?

Not sure such thing exists. You could check RAA. If not, you can
pretty easily implement something yourself using Find and File#size or
File#stat and some additional logic that takes into account the
clustering size of the file system.

Cheers

robert


#4

On Mon, 30 Mar 2009, Juan Z. wrote:

I was wondering if there was something to du -h?

Umm, it’s pretty ugly what I do have… it invokes the Linux statfs
system call…

$ irb -r StatFs64.rb
irb(main):001:0> a = StatFs64.new( “/home”)
=> #<StatFs64:0xb7cd8108 @statfs64={“f_spare0”=>0, “f_spare1”=>0,
“f_files”=>5750784, “f_bfree”=>3332642, “f_bsize”=>4096, “f_spare2”=>0,
“f_blocks”=>11299984, “f_spare3”=>0, “f_spare4”=>0, “f_ffree”=>4574344,
“f_fsid0”=>1992275371, “f_fsid1”=>157862524, “f_frsize”=>4096,
“f_namelen”=>255, “f_bavail”=>2758620, “f_type”=>61267}>
irb(main):002:0> p a.free_gigabytes
10.5233001708984
=> nil

John C. Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : removed_email_address@domain.invalid
New Zealand


=begin rdoc
This stuff can depend on the exact version of linux you have.
Ugly, I know.

extension typedef unsigned long long int __u_quad_t;
extension typedef __u_quad_t __fsblkcnt64_t;
extension typedef __u_quad_t __fsfilcnt64_t;
extension typedef struct { int __val[2]; } __fsid_t;

struct statfs64
{
int f_type;
int f_bsize;
__fsblkcnt64_t f_blocks;
__fsblkcnt64_t f_bfree;
__fsblkcnt64_t f_bavail;
__fsfilcnt64_t f_files;
__fsfilcnt64_t f_ffree;
__fsid_t f_fsid;
int f_namelen;
int f_frsize;
int f_spare[5];
};

#define __NR_statfs64 268
#define __NR_fstatfs64 269

I dug the above info out using the follow trick…
tmp = “/tmp/struct.c”
open(tmp, ‘w’) do |c|
c.puts "
#define _GNU_SOURCE 1
#include <sys/syscall.h>
#include <sys/statfs.h>

struct statfs64 s;

"
end

puts gcc -E #{tmp}

=end

require ‘pp’

class StatFs64
STRUCT_STATFS64 = [
[0, ‘i’, ‘f_type’],
[0, ‘i’, ‘f_bsize’],
[0, ‘Q’, ‘f_blocks’],
[0, ‘Q’, ‘f_bfree’],
[0, ‘Q’, ‘f_bavail’],
[0, ‘Q’, ‘f_files’],
[0, ‘Q’, ‘f_ffree’],
[0, ‘i’, ‘f_fsid0’],
[0, ‘i’, ‘f_fsid1’],
[0, ‘i’, ‘f_namelen’],
[0, ‘i’, ‘f_frsize’],
[0, ‘i’, ‘f_spare0’],
[0, ‘i’, ‘f_spare1’],
[0, ‘i’, ‘f_spare2’],
[0, ‘i’, ‘f_spare3’],
[0, ‘i’, ‘f_spare4’],
]

def syscall_pack( triplets)
template = ‘’
default = []
triplets.each do |value, directive, name|
default << value
template += directive
end
default.pack( template)
end

def syscall_unpack( triplets, string)
template = ‘’
names = []
triplets.each do |value, directive, name|
names << name
template += directive
end

 result = {}
 values = string.unpack( template)
 names.each_with_index do |name,i|
   value = values[i]
   result[name] = value
 end

 result

end

def initialize( path)
string = syscall_pack( STRUCT_STATFS64)
result = syscall( 268, path, string.size, string)
raise “Unexpected return value ‘#{result}’” unless
result == 0

 @statfs64 = syscall_unpack( STRUCT_STATFS64, string)

end

def free_megabytes
(@statfs64[‘f_bavail’] * @statfs64[‘f_bsize’]) / (1024 * 1024.0)
end

def free_gigabytes
free_megabytes / 1024.0
end

attr_reader :statfs64
end


#5

For the web archive :slight_smile: my slightly shorter effort, possibly more
portable, is attached. It relies on libffi being installed:

module Linux; module StatFs

The result of a statfs operation, see “man statfs” for more

information

on each field. We add some helper methods that deal in bytes.

class Result < Struct.new(:type, :bsize, :blocks, :bfree, :bavail,
:files, :ffree)
def total; blocks * bsize; end
def free; bfree * bsize; end
def avail; bavail * bsize; end
end

module Lib
extend FFI::Library
ffi_lib FFI::Library::LIBC
attach_function ‘statfs64’, [:string, :pointer], :int
end

Drives the interface to the C library, returns a StatFs::Result

object

to show filesystem information for the given path.

def self.statfs(path)
output = FFI::MemoryPointer.new(128)
begin
error_code = Lib::statfs64(path, output)
raise “statfs raised error #{error_code}” if error_code != 0
return Result.new(*output[0].read_array_of_long(7))
ensure
output.free
end
end

end; end

I’ve only tested it to see that the results tally with “df”, so e.g. to
find the number of free bytes on your root, you run:

Linux::StatFs.statfs("/").free

Regards,


Matthew B.


#6

John C. wrote:

On Mon, 30 Mar 2009, Juan Z. wrote:

I was wondering if there was something to du -h?

Umm, it’s pretty ugly what I do have… it invokes the Linux statfs
system call…

gem install sys-filesystem

Regards,

Dan