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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
01cd7a5d8751789819701518f3fe6ffa?d=identicon&s=25 Juan Zanos (Guest)
on 2009-03-29 22:00
(Received via mailing list)
I was wondering if there was something to du -h?

Juan
Da22709962fc0cf31068e779c78ab6be?d=identicon&s=25 Raveendran .P (jazzezravi)
on 2009-03-30 06:09
Juan Zanos 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    <DIR>          .
12/26/2008  05:14 PM    <DIR>          ..
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
http://raveendran.wordpress.com
D812408537ac3a0fa2fec96eb8811559?d=identicon&s=25 John Carter (johncarter)
on 2009-03-30 06:21
(Received via mailing list)
On Mon, 30 Mar 2009, Juan Zanos 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 Carter                             Phone : (64)(3) 358 6639
Tait Electronics                        Fax   : (64)(3) 359 4632
PO Box 1645 Christchurch                Email : john.carter@tait.co.nz
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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2009-03-30 07:55
(Received via mailing list)
On 29.03.2009 21:58, Juan Zanos 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
Aee77dba395ece0a04c688b05b07cd63?d=identicon&s=25 Daniel Berger (djberg96)
on 2009-03-30 11:55
(Received via mailing list)
John Carter wrote:
> On Mon, 30 Mar 2009, Juan Zanos 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...

<snip>

gem install sys-filesystem

Regards,

Dan
8596fe013923e480f8278e6f5e1dca43?d=identicon&s=25 Matthew Bloch (matthew_b)
on 2010-11-19 20:30
For the web archive :) 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 Bloch
This topic is locked and can not be replied to.