Ruby Human Readable File Sizes

Ruby Human Readable File Sizes

Printing a human readable file size or folder size or S3 bucket size in Ruby is a common use case.

Let’s use and improve the Ruby filesize gem to pretty print and deliver human readable disk storage sizes in bytes, kilobytes, megabytes, gigabytes, terrabytes and petabytes.

Install the filesize gem

Install the Ruby filesize gem either using your gem file or with this command.

gem install filesize

Use require 'filesize' in your Ruby script to import the filesize gem.

Is the human readable filesize pretty enough

Unfortunately the filesize gem output is not that pretty – but it is easy to improve it to display file sizes in a conventional manner.

    size_in_bytes = 24253
    unpretty_size = Filesize.from("#{size_in_bytes} b").pretty
    puts "The unpretty size is #{unpretty_size}"

The unpretty size is [23.71 KiB]

Now this is unpretty because

  1. It shows 2 decimal places (not human readable).
  2. It adds square brackets which you may not want.
  3. The letter i is sandwiched so MiB, KiB, GiB results.
  4. a distracting space exists after the floating point.

The Ruby script below negates all the issues.

Ruby Script for Human Readable File Sizes

This Ruby method cleans the filesize gem output to present a truly human readable file size. What’s more – you can tweak the output to suit your needs. The argument is the size in bytes.

  # -- ----------------------------------------------------------------------------------- -- #
  # -- Pretty print storage sizes in bytes, kilobytes, megabytes, gigabytes and terrabytes -- #
  # -- ----------------------------------------------------------------------------------- -- #
  def pretty_print_size size_in_bytes

    unpretty_size = Filesize.from("#{size_in_bytes} b").pretty
    two_part_hash = unpretty_size.delete("i[]").split
    int_size = two_part_hash[0].to_f.round
    readable_byte_size = "( #{size_in_bytes} bytes )"

    if( two_part_hash[1].length == 1 )
      return readable_byte_size
    end

    return "#{int_size}#{two_part_hash[1][0]} #{readable_byte_size}"

  end

The string.delete call removes character (not string) occurrences.

my_string.delete("i[]")

It does not search for a string “i[]” – it removes the character i, any opening and closing square brackets. Exactly what we want.

The split gives us a floating point number and the size units (now KB, MB, TB, GB) in an array.

We round the first part of the array (after converting the string to a float). If the size is small, like 428 bytes it returns (428 bytes).

For 1000 bytes and over we have formatted it to return say 25K (2653 bytes).

If you don’t want to see the bytes equivalent (input) number, change the final line to the below.

    return "#{int_size}#{two_part_hash[1][0]}"

Now your Ruby scripts can pretty print human readable sizes in a human readable form.

Leave a Reply

Your email address will not be published. Required fields are marked *