Skip to content
Daniel Berger edited this page Jun 12, 2016 · 24 revisions

The win32-file-stat gem

The win32-file-stat gem redefines several core File::Stat methods so that they work (or work properly) on MS Windows. It also adds one new method.

Caveats

Generally speaking you should not require this gem directly, but should require "win32-file" instead, which in turn will load this library. This is because most external libraries use the pass-through methods of the File class rather than File::Stat directly, e.g. File.blksize instead of File::Stat#blksize. Failure to follow this advice could lead to unexpected errors.

Redefined Methods

File::Stat#blksize

This method is unimplemented in core Ruby and returns nil. Using the win32-file-stat gem it returns the actual block size value. Normally this is 4k.

# MRI
File::Stat.new("C:\\").blkize # => nil

# win32-file-stat
File::Stat.new("C:\\").blksize # => 4096

File::Stat#blockdev?

This method is unimplemented in core Ruby and always returns false. Using the win32-file-stat gem it returns true for ramdisks, removable drives and cd/dvd drives.

File::Stat#blocks

This method is unimplemented in core Ruby and returns nil. Using the win32-file-stat gem it returns the number of blocks consumed by the file based on the File::Stat#blksize method above.

File::Stat#executable?

This method is unimplemented in core Ruby and always returns true. Using the win32-file-stat gem it only returns true for .com, .bat, .cmd and .exe files.

File::Stat#executable_real?

This method is unimplemented in core Ruby. Using the win32-file-stat gem it is simply an alias for File::Stat#executable? above.

File::Stat#file?

This method is unimplemented in core Ruby and always returns false. Using the win32-file-stat gem it returns true if the file is a "normal" file and not a directory or reparse point.

File::Stat#ftype

This method is partially implemented in core Ruby, but everything is either "file" and "directory". Using the win32-file-stat gem, it also distinguishes "characterSpecial", "blockSpecial", and "socket".

File::Stat#gid

This method is unimplemented in core Ruby and always returns 0. Using the win32-file-stat it returns the relative group ID of the security identifier, i.e. the RID of the SID.

In addition, it accepts an optional boolean argument that, if true, will return the full SID.

# MRI
File::Stat.new("README") # => 0

# win32-file-stat
File::Stat.new("README").gid       # => 501
File::Stat.new("README").gid(true) # => "S-1-5-21-11112222333-12345-6789-501"

File::Stat#grpowned?

This method is unimplemented in core Ruby and always returns true. Using the win32-file-stat gem, it will actually check the group SID of the file versus the SID of the current process. Only if they match does it return true.

File::Stat#ino

This method is unimplemented in core Ruby and always returns 0. Using the win32-file-stat gem, it will instead return the file's unique index identifier, which we felt was a pretty good analogue.

File::Stat#inspect

This was redefined to properly include the information from the redefined methods, as well as the File::Stat#streams method.

File::Stat#owned?

This method is unimplemented in core Ruby and always returns true. Using the win32-file-stat gem, it will actually check the user SID of the file versus the SID of the current process. Only if they match does it return true.

File::Stat#pipe?

This method is unimplemented in core Ruby and always returns false. Using the win32-file-stat gem it returns true only if it's actually a pipe.

File::Stat#pretty_print

This method was redefined so that the pp library would properly print the output of the updated File::Stat object.

File::Stat#rdev

Prior to Ruby 2.2.x this method was a synonym for File::Stat#dev, and so it was redefined to return the volume serial number.

For Ruby 2.2 or later this method behaves identically, and so our custom method will eventually be removed.

File::Stat#socket?

This method is unimplemented in core Ruby and always returns false. Using the win32-file-stat gem it returns true only if it's actually a socket.

File::Stat#symlink?

This method was unimplemented in core Ruby until Ruby 2.3.x. Even then, it is still buggy since it treats reparse points as symlinks. See https://bugs.ruby-lang.org/issues/11478 for details.

For now, we have left our implementation in.

File::Stat#uid

This method is unimplemented in core Ruby and always returns 0. Using the win32-file-stat it returns the relative user ID of the security identifier, i.e. the RID of the SID.

In addition, it accepts an optional boolean argument that, if true, will return the full SID.

# MRI
File::Stat.new("README") # => 0

# win32-file-stat
File::Stat.new("README").uid       # => 1001
File::Stat.new("README").uid(true) # => "S-1-5-21-11112222333-12345-6789-1001"

New Methods

File::Stat#streams

Returns an array of data streams for the given file, including the default $DATA stream.

File::Stat.new("README").streams # => ["::$DATA"]