tags:

views:

90

answers:

2

Possible Duplicate:
Reusable library to get human readable version of file size?

Hi,

How can I convert a number (file size in bytes) to a string like the --human-readable option does in some UNIX commands ?

Examples :

42e5 => 4.2M

2000 => 2.0K

Many thanks !

+1  A: 

Similar questions were asked a number of times, but I can share yet another implementation:

from math import log10

KB = 1024
MB = KB * KB
GB = MB * KB
TB = GB * KB

def human_size(s):
    """
    >>> human_size(1)
    '1 B'
    >>> human_size(123)
    '123 B'
    >>> human_size(1001)
    '0.98 KB'
    >>> human_size(23456)
    '22.9 KB'
    """
    units = [(0, 1, "B"), (1000, KB, "KB"), (1000*KB, MB, "MB"),
             (1000*MB, GB, "GB"), (1000*GB, TB, "TB")]
    for limit, div, unit in reversed(units):
        if s > limit:
            s = float(s) / div
            log = int(log10(s))
            if s > 1000:
                s = round(s)
            else:
                norm = 10 ** (log - 2)
                s = round(float(s) / norm) * norm
            prec = (0 if div == 1 else max(2 - log, 0))
            return '%.*f %s' % (prec, s, unit)
rkhayrov
A: 

These are the two functions I use.

  • isiz2str is simpler but rounds sizes to integers.
  • fsiz2str may be more like what you are looking for.

    def isiz2str(siz):  
        m='okMGT'  
        i=0  
        while siz>999:  
            siz/=1000.0  
            i+=1  
        return '%3.0F %s' % (siz, m[i])  
    
    
    def fsiz2str(n):
        i=int(n)
        if i>=1:
            m=' oookkkMMMGGGTTT'
            s3s=0
            l=1
            s=str(i)
            s3=int(s[:3])
            l=len(s)
            k=l/3
            r=l-k*3
            if r and k:
                s3/=pow(10, (3.0-r))
            s3s=str(s3)
            if len(s3s)<4 and '.' in s3s:
                s3s+='0'
            return '%4s %s' % (s3s, m[l])
    

These functions are designed to be easily extendable. If we want to handle Peta we only have to modify the m value.
fsiz2str is designed to always return 3 significant digits so that the strings returned always have the same size (6 char).

dugres