Rand Stats

File::Stat

zef:elcaro

NAME

File::Stat - Access file stat fields

SYNOPSIS

Implements a File::Stat class, as well as exportable stat and lstat functions that will return a File::Stat object.

This object has methods that return the similarly named structure field name from the stat(2) function.

use File::Stat < stat lstat >;

say File::Stat.new(path => $?FILE).mode;
say stat($?FILE).uid

# or use `lstat`

say File::Stat.new(path => $?FILE, :l).mode;
say lstat($?FILE).uid

# Augment your IO::Path, stat!

role Stat {
    method stat { File::Stat.new(path => self) }
}

my $file = $?FILE.IO but Stat;
say ($file.s, $file.stat.blksize);

ALTERNATIVES

When this module was first written, there was no easy way to get certain stat fields (eg. gid) from an IO::Path object. Since then, several methods have been added to IO::Path to access those fields, which means you may not even need this module!

Below I will document the methods provided by File::Stat, and - where available - the equivalent core IO::Path method (as well as any differences).

Initial descriptions below are verbatim from man 2 stat.

METHODS

dev

This field describes the device on which this file resides.

Core alternative: IO::Path.dev

say stat($?FILE).dev;
say $?FILE.IO.dev;

ino

This field contains the file's inode number.

Core alternative: IO::Path.inode

say stat($?FILE).ino;
say $?FILE.IO.inode;

mode

This field contains the file type and mode.

Core alternative: IO::Path.mode

NOTE: The IO::Path.mode method only returns the 8-least significant bits, as the higher bits are not platform-independent.

my &permissions = *.base(2).flip.comb(3)».flip.reverse;

say permissions( stat($?FILE).mode );  # (1 000 000 111 101 101)
say permissions( $?FILE.IO.mode );     #           (111 101 101)

See also: IO::Path methods .r, .w, .x., .rw, .rwx, .f, .d;

This field contains the number of hard links to the file.

Core alternative: None that I'm aware of. Send PR if this changes.

say stat($?FILE).nlink;

uid

This field contains the user ID of the owner of the file.

Core alternative: IO::Path.user

say stat($?FILE).uid;
say $?FILE.IO.user;

gid

This field contains the ID of the group owner of the file.

Core alternative: IO::Path.group

say stat($?FILE).gid;
say $?FILE.IO.group;

rdev

This field describes the device that this file (inode) represents.

Core alternative: IO::Path.devtype

say stat($?FILE).rdev;
say $?FILE.IO.devtype;

size

This field gives the size of the file (if it is a regular file or a symbolic link) in bytes. The size of a symbolic link is the length of the pathname it contains, without a terminating null byte.

Core alternative: IO::Path.s

say stat($?FILE).size;
say $?FILE.IO.s;

atime

This is the time of the last access of file data.

Core alternative: IO::Path.accessed

NOTE: See "TIME DIFFERENCES" section.

say stat($?FILE).atime;  # --> Int
say $?FILE.IO.accessed;  # --> Instant

mtime

This is the time of last modification of file data.

Core alternative: IO::Path.modified

NOTE: See "TIME DIFFERENCES" section.

say stat($?FILE).mtime;  # --> Int
say $?FILE.IO.modified;  # --> Instant

ctime

This is the file's last status change timestamp (time of last change to the inode).

Core alternative: IO::Path.created

NOTE: See "TIME DIFFERENCES" section.

say stat($?FILE).ctime;  # --> Int
say $?FILE.IO.created;   # --> Instant

blksize

This field gives the "preferred" block size for efficient filesystem I/O.

Core alternative: None that I'm aware of. Send PR if this changes.

say stat($?FILE).blksize;

blocks

This field indicates the number of blocks allocated to the file, in 512-byte units. (This may be smaller than size/512 when the file has holes.)

Core alternative: None that I'm aware of. Send PR if this changes.

say stat($?FILE).blocks;

ADDITIONAL METHODS

Hash

You can return all fields as a Hash.

Useful if you want to pull out multiple fields (via a hash slice) or convert to JSON (or other format).

say stat($?FILE).Hash

TIME DIFFERENCES

The time related functions (eg. mtime) will differ slightly from their core alternatives (eg. modified).

This module will return an Int, where as the IO::Path method will return an Instant. You may notice that when this Instant is coerced to an Int that there is a difference of 37 seconds.

say stat($?FILE).mtime;      # 1692319800
say $?FILE.IO.modified.Int;  # 1692319837

However, when converting to a DateTime object, both should resolve the same second.

say DateTime.new(stat($?FILE).mtime);  # 2023-08-18T00:50:00Z
say $?FILE.IO.modified.DateTime;       # 2023-08-18T00:50:00.837761Z

This difference is due to leap-seconds, of which Raku is aware.

CAVEATS

The File::Stat class provides dynamic access to the stat fields, they are not static attributes. This means, for example, that even after you create a File::Stat object, calling .size on the instance can change between calls. This is in line with what IO::Path.s would do, but may not be what you expect.

Some methods do not mean anything in non-POSIX systems.

This module uses NQP ops.