Python libraries to calculate human readable filesize from bytes?

I find hurry.filesize very useful but it doesn't give output in decimal?

For example:

print size(4026, system=alternative) gives 3 KB.

But later when I add all the values I don't get the exact sum. For example if the output of hurry.filesize is in 4 variable and each value is 3. If I add them all, I get output as 15.

I am looking for alternative of hurry.filesize to get output in decimals too.


This isn't really hard to implement yourself:

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
def humansize(nbytes):
    i = 0
    while nbytes >= 1024 and i < len(suffixes)-1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])


>>> humansize(131)
'131 B'
>>> humansize(1049)
'1.02 KB'
>>> humansize(58812)
'57.43 KB'
>>> humansize(68819826)
'65.63 MB'
>>> humansize(39756861649)
'37.03 GB'
>>> humansize(18754875155724)
'17.06 TB'

Disclaimer: I wrote the package I'm about to describe

The module bitmath supports the functionality you've described. It also addresses the comment made by @filmore, that semantically we should be using NIST unit prefixes (not SI), that is to say, MiB instead of MB. rounding is now supported as well.

You originally asked about:

print size(4026, system=alternative)

in bitmath the default prefix-unit system is NIST (1024 based), so, assuming you were referring to 4026 bytes, the equivalent solution in bitmath would look like any of the following:

In [1]: import bitmath

In [2]: print bitmath.Byte(bytes=4026).best_prefix()

In [3]: human_prefix = bitmath.Byte(bytes=4026).best_prefix()

In [4]: print human_prefix.format("{value:.2f} {unit}")
3.93 KiB

I currently have an open task to allow the user to select a preferred prefix-unit system when using the best_prefix method.

Update: 2014-07-16 The latest package has been uploaded to PyPi, and it includes several new features (full feature list is on the GitHub page)

This is not necessary faster than the @nneonneo solution, it's just a bit cooler, if I can say that :)

import math

suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']

def human_size(nbytes):
  human = nbytes
  rank = 0
  if nbytes != 0:
    rank = int((math.log10(nbytes)) / 3)
    rank = min(rank, len(suffixes) - 1)
    human = nbytes / (1024.0 ** rank)
  f = ('%.2f' % human).rstrip('0').rstrip('.')
  return '%s %s' % (f, suffixes[rank])

This works based on the fact that the integer part of a logarithm with base 10 of any number is one less than the actual number of digits. The rest is pretty much straight forward.

Need Your Help

What is the difference between up-casting and down-casting with respect to class variable

java casting class-variables downcast upcasting

What is the difference between up-casting and down-casting with respect to class variable?

Reversing single linked list in C#

c# reverse singly-linked-list

I am trying to reverse a linked list. This is the code I have come up with: