use-strict.de

Perl: Obtain the size of a file in a human readable format

While machines easily process large numbers without trouble, (most) humans don't possess this ability. As a result, any filesize reported to a user should be in a more handy format. This article shows how to achieve this with Perl.

In order to obtain a file's size, Perl's builtin function stat can be utilized to determine the bytes it occupies. This count can then be convert into a human readable format, whenever it is reported to a user.

However, there is alot of confusion about the commonly used units and their actual meaning. I.e., how many bytes does a Megabyte consist of? 1,048,576 (1024 1024) or 1,000,000 (1000 1000)?

In order to return an unambigious result, the following subroutine, get_filesize_str(), uses IEC binary prefixes to indicate that the units are describing multiples of two, rather then ten. Read the related Wikipedia article for details on binary prefixes.

sub get_filesize_str
{
    my $file = shift();

    my $size = (stat($file))[7] || die "stat($file): $!\n";

    if ($size > 1099511627776)  #   TiB: 1024 GiB
    {
        return sprintf("%.2f TiB", $size / 1099511627776);
    }
    elsif ($size > 1073741824)  #   GiB: 1024 MiB
    {
        return sprintf("%.2f GiB", $size / 1073741824);
    }
    elsif ($size > 1048576)     #   MiB: 1024 KiB
    {
        return sprintf("%.2f MiB", $size / 1048576);
    }
    elsif ($size > 1024)        #   KiB: 1024 B
    {
        return sprintf("%.2f KiB", $size / 1024);
    }
    else                        #   bytes
    {
        return "$size byte" . ($size == 1 ? "" : "s");
    }
}

Download this subroutine.

For a much more sophisticated approach, have a look at the Number::Bytes::Human module by Adriano Ferreira on CPAN.