Parent

Included Modules

Sys::Filesystem

The Filesystem class encapsulates information about your filesystem.


The Filesystem class serves as an abstract base class. Its methods return objects of other types. Do not instantiate.

Public Class Methods

mount_point(file) click to toggle source

Returns the mount point for the given file. For MS Windows this means the root of the path.

Example:

File.mount_point("C:\\Documents and Settings") # => "C:\\'
# File lib/windows/sys/filesystem.rb, line 229
def self.mount_point(file)
  wfile = FFI::MemoryPointer.from_string(file.wincode)

  if PathStripToRootW(wfile)
    wfile.read_string(wfile.size).split("\0000\0000").first.tr(0.chr, '')
  else
    nil
  end
end
mounts() click to toggle source

Yields a Filesystem::Mount object for each volume on your system in block form. Returns an array of Filesystem::Mount objects in non-block form.

Example:

Sys::Filesystem.mounts{ |mount|
   p mt.name        # => \\Device\\HarddiskVolume1
   p mt.mount_point # => C:\
   p mt.mount_time  # => Thu Dec 18 20:12:08 -0700 2008
   p mt.mount_type  # => NTFS
   p mt.options     # => casepres,casesens,ro,unicode
   p mt.pass_number # => nil
   p mt.dump_freq   # => nil
}

This method is a bit of a fudge for MS Windows in the name of interface compatibility because this method deals with volumes, not actual mount points. But, I believe it provides the sort of information many users want at a glance.

The possible values for the options and their meanings are as follows:

casepres => The filesystem preserves the case of file names when it places a name on disk. casesens => The filesystem supports case-sensitive file names. compression => The filesystem supports file-based compression. namedstreams => The filesystem supports named streams. pacls => The filesystem preserves and enforces access control lists. ro => The filesystem is read-only. encryption => The filesystem supports the Encrypted File System (EFS). objids => The filesystem supports object identifiers. rpoints => The filesystem supports reparse points. sparse => The filesystem supports sparse files. unicode => The filesystem supports Unicode in file names as they appear on disk. compressed => The filesystem is compressed.

# File lib/windows/sys/filesystem.rb, line 145
def self.mounts
  # First call, get needed buffer size
  buffer = 0.chr
  length = GetLogicalDriveStringsA(buffer.size, buffer)

  if length == 0
    raise SystemCallError.new('GetLogicalDriveStrings', FFI.errno)
  else
    buffer = 0.chr * length
  end

  mounts = block_given? ? nil : []

  # Try again with new buffer size
  if GetLogicalDriveStringsA(buffer.size, buffer) == 0
    raise SystemCallError.new('GetLogicalDriveStrings', FFI.errno)
  end

  drives = buffer.split(0.chr)

  boot_time = get_boot_time

  drives.each{ |drive|
    mount  = Mount.new
    volume = FFI::MemoryPointer.new(:char, MAXPATH)
    fsname = FFI::MemoryPointer.new(:char, MAXPATH)

    mount.instance_variable_set(:@mount_point, drive)
    mount.instance_variable_set(:@mount_time, boot_time)

    volume_serial_number = FFI::MemoryPointer.new(:ulong)
    max_component_length = FFI::MemoryPointer.new(:ulong)
    filesystem_flags     = FFI::MemoryPointer.new(:ulong)

    bool = GetVolumeInformationA(
       drive,
       volume,
       volume.size,
       volume_serial_number,
       max_component_length,
       filesystem_flags,
       fsname,
       fsname.size
    )

    # Skip unmounted floppies or cd-roms, or inaccessible drives
    unless bool
      if [5,21].include?(FFI.errno) # ERROR_NOT_READY or ERROR_ACCESS_DENIED
        next
      else
        raise SystemCallError.new('GetVolumeInformation', FFI.errno)
      end
    end

    filesystem_flags = filesystem_flags.read_ulong
    fsname = fsname.read_string

    name = 0.chr * MAXPATH

    if QueryDosDeviceA(drive[0,2], name, name.size) == 0
      raise SystemCallError.new('QueryDosDevice', FFI.errno)
    end

    mount.instance_variable_set(:@name, name.strip)
    mount.instance_variable_set(:@mount_type, fsname)
    mount.instance_variable_set(:@options, get_options(filesystem_flags))

    if block_given?
      yield mount
    else
      mounts << mount
    end
  }

  mounts # Nil if the block form was used.
end
stat(path) click to toggle source

Returns a Filesystem::Stat object that contains information about the path file system.

Examples:

File.stat("C:\\")
File.stat("C:\\Documents and Settings\\some_user")
# File lib/windows/sys/filesystem.rb, line 247
def self.stat(path)
  bytes_avail = FFI::MemoryPointer.new(:ulong_long)
  bytes_free  = FFI::MemoryPointer.new(:ulong_long)
  total_bytes = FFI::MemoryPointer.new(:ulong_long)

  wpath = path.wincode

  unless GetDiskFreeSpaceExW(wpath, bytes_avail, total_bytes, bytes_free)
    raise SystemCallError.new('GetDiskFreeSpaceEx', FFI.errno)
  end

  bytes_avail = bytes_avail.read_ulong_long
  bytes_free  = bytes_free.read_ulong_long
  total_bytes = total_bytes.read_ulong_long

  sectors = FFI::MemoryPointer.new(:ulong_long)
  bytes   = FFI::MemoryPointer.new(:ulong_long)
  free    = FFI::MemoryPointer.new(:ulong_long)
  total   = FFI::MemoryPointer.new(:ulong_long)

  unless GetDiskFreeSpaceW(wpath, sectors, bytes, free, total)
    raise SystemCallError.new('GetDiskFreeSpace', FFI.errno)
  end

  sectors = sectors.read_ulong_long
  bytes   = bytes.read_ulong_long
  free    = free.read_ulong_long
  total   = total.read_ulong_long

  block_size   = sectors * bytes
  blocks_avail = total_bytes / block_size
  blocks_free  = bytes_free / block_size

  vol_name   = FFI::MemoryPointer.new(:char, MAXPATH)
  base_type  = FFI::MemoryPointer.new(:char, MAXPATH)
  vol_serial = FFI::MemoryPointer.new(:ulong)
  name_max   = FFI::MemoryPointer.new(:ulong)
  flags      = FFI::MemoryPointer.new(:ulong)

  bool = GetVolumeInformationW(
    wpath,
    vol_name,
    vol_name.size,
    vol_serial,
    name_max,
    flags,
    base_type,
    base_type.size
  )

  unless bool
    raise SystemCallError.new('GetVolumInformation', FFI.errno)
  end

  vol_serial = vol_serial.read_ulong
  name_max   = name_max.read_ulong
  flags      = flags.read_ulong
  base_type  = base_type.read_string(base_type.size).tr(0.chr, '')

  stat_obj = Stat.new
  stat_obj.instance_variable_set(:@path, path)
  stat_obj.instance_variable_set(:@block_size, block_size)
  stat_obj.instance_variable_set(:@blocks, blocks_avail)
  stat_obj.instance_variable_set(:@blocks_available, blocks_avail)
  stat_obj.instance_variable_set(:@blocks_free, blocks_free)
  stat_obj.instance_variable_set(:@name_max, name_max)
  stat_obj.instance_variable_set(:@base_type, base_type)
  stat_obj.instance_variable_set(:@flags, flags)
  stat_obj.instance_variable_set(:@filesystem_id, vol_serial)

  stat_obj.freeze # Read-only object
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.